views:

117

answers:

4

Hi, After doing a long search on stackoverflow i didn't find any one talked about this even if it's a big choice, the Question is what's the best in order to prevent both of XSS and SQL injection, Escaping the data then store it in the DB or Store it as it is and escape when output it?

Note: it is better if you give some examples of practics if possible.

Thanks

+1  A: 

Escape input, store, then escape output.


If you store without escaping, you're vulnerable to SQL injection.

Example: You have a query:

mysql_query("SELECT * FROM `table` WHERE `abc`= '{$_POST['def']}';

Let's say that $_POST['def'] is equal to

blah'; DROP TABLE `table`; SELECT * FROM `table` WHERE 'abc' = '123

That will cause your table to be dropped if it's not escaped.


If you output without escaping, you're vulnerable to XSS.

Otherwise, users can inject harmful Javascript into pages other users can view.

waiwai933
Well, not quite true in the specific example case. `mysql_query()` does not support multiple queries.
Chad Birch
+6  A: 

The data must be properly SQL-escaped (or sent separately from the SQL, as others suggest) for storage, and HTML-escaped for display.

SamB
Note the difference between escaping for sql, and escaping for html.
chris
Yes, the escapings are quite different, and it is vital to use the correct one in each case.
SamB
+2  A: 

Your question doesn't make much sense, because the very act of trying to store data containing an SQL injection is what causes the SQL injection.

Either way, you should be using Parameterized queries to prevent SQL injection.

For XSS/HTML escaping, I'd personally rather do it at insertion-time, because then you only have to do that processing once, instead of every time it's displayed. A small optimization, but an easy one.

Chad Birch
Its wrong to escape at insertion time. At insertion time, you don't know where the string is going to be used. For example, you may want to send the string to HTML or javascript, or you may want to use the string as a query parameter in a url. Or you may want to perform some analysis on your string once its stored in the database. Each of these use cases has a different escape method.
sri
In some specific cases, sanitizing (e.g. stripping HTML) is appropriate. For example, a field holding a URL shouldn't store HTML. Also, a field holding someone's given name shouldn't store HTML. A field holding a full name, however, might someday store it as XML to delineate given and surnames, so it likely shouldn't be stripped. Consideration must be given to what formats can be stored in a field.
outis
+4  A: 

In order, you should do the following -

  1. Validate the input to see if it meets your expectation. If it doesn't, reject the input and stop. If it meets, continue to next step without altering the input.

  2. Bind the input to a parameterized query, or escape the input as you are forming the query. Note that escaping the input does not alter the input. The database will always contain the exact string the user entered.

  3. When displaying to the user, you have to escape it according to the context. There are around 5 distinct ways in which the same string can be escaped - depending on whether you are displaying it in HTML element, HTML attribute, Javascript, CSS, or as a URL. See http://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet. Again, remember that escaping doesn't alter the string. The user must always see the exact string he had entered.

You may be tempted to store a modified string in the database - but please don't do so. If you escape it for HTML, you can never use the string in javascript. If you have to do back-end processing, you'd have to de-escape the string. You will soon reach a stage where you can't do the right thing anymore.

Remember that escaping is just a way to transport data from one layer to another. At rest (database or screen), the data should look exactly the way the user entered it.

sri