I've used mysql_real_escape_string()
to sanitise data when inserting it into the database, is it okay to use it again when retrieving data from the database?

- 13,139
- 14
- 57
- 108

- 1,194
- 15
- 19
-
3If you're attempting to reverse the escaping for display purposes, try `stripslashes()`. – showdev Feb 06 '13 at 23:53
-
does it mean that if I store something like //name> it would be returned as name? – Acheme Paul Feb 07 '13 at 00:01
-
1@showdev `stripslashes()` only needs to be used on input data from forms if you can't turn off magic quotes in your PHP isntance. – staticsan Feb 07 '13 at 00:08
-
1You're doing it wrong! You should not be using `ext/mysql`. Instead use PDO or mysqli. – Mike Feb 07 '13 at 00:09
-
@staticsan Not exactly true -- there are other uses. I have used stripslashes() in the past (with old mysql_* code) to remove escaping from data pulled from the database. Otherwise it can be displayed with slashes. – showdev Feb 07 '13 at 00:12
-
@showdev For old data and old code that had escaping problems, yes, I agree. – staticsan Feb 07 '13 at 00:15
-
If you're asking this many questions about SQL escaping, you should probably use a [PHP framework](http://www.phpframeworks.com/top-10-php-frameworks/) that can do it for you. – tadman Feb 07 '13 at 01:45
3 Answers
It's not ok to use it at any time. The MySQL extension has been deprecated. Use PDO or MySQLi instead.
When using data in a query, use parameter binding instead of string manipulation for sanitising purposes.
You do not need to sanitise data on retrieval. If you're displaying the data in an HTML page, use the htmlspecialchars()
or htmlentities()
functions instead.
Update
To explain, you should not be storing data with escape characters in it. The best approach is to store data as received without modification (this is external to any validation you use to filter inputs prior to storing).
PDO and MySQLi both support parameter binding which is the safest way to store volatile data, eg (PDO)
$stmt = $pdo->prepare('INSERT INTO tableName VALUES (:param1, :param2)');
$stmt->bindParam('param1', $var1);
$stmt->bindParam('param2', $var2);
$stmt->execute();
Upon retrieval, you will receive the data as it went in so you do not need to modify it again.
To safely display this data in an HTML page, use one of the encoding functions listed above, eg
$stmt = $pdo->prepare('SELECT name FROM tableName');
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
?>
<p>Hello, <?= htmlspecialchars($row['name']) ?></p>

- 157,677
- 23
- 242
- 245
-
3Arrrggghhh the `stripslashes()` recommendations are hurting my eyes! – Dan Blows Feb 07 '13 at 00:02
-
1
-
Good advice, Phil. My suggestion assumes (as the OP suggested) that `mysql_real_escape_string()` is already being used. stripslashes is not depreciated... – showdev Feb 07 '13 at 00:05
-
@showdev I never said `stripslashes()` was deprecated. In any case, it's only use is to undo magic quotes (which shouldn't be enabled anyway) or reverse `addslashes()`. It should not be used around query parameters at all – Phil Feb 07 '13 at 00:13
-
@Phil I believe the OP was asking about escpaing data coming out of the database. The issue of which function to use for escaping is a secondary issue. – staticsan Feb 07 '13 at 00:13
-
@Phil I didn't mean to suggest that you said stripslashes() is depreciated. I was referring more to Blowski's comment. Sorry about that. – showdev Feb 07 '13 at 00:18
No, mysql_real_escape_string()
(and it's more modern version mysqli::real_escape_string()
) should not be used on data retrieved from the database.
The only reason for escaping data for insertion into the database is because you are assembling it as string-data in another language: SQL. That is the purpose of escaping. If there was an API call where you provided all the elements as discrete parameters, you would not need to escape the data. But that's not how SQL works.
(Similarly, stripslashes()
is only needed if you can't turn off magic quotes in your PHP instance.)

- 29,935
- 4
- 60
- 73
-
1If you can't turn off magic quotes, host your application somewhere else. Having it on is insane. – tadman Feb 07 '13 at 01:41
Yes always.
$username = stripslashes($_POST['username']);
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string(md5($_POST['password']));//with md5
And retrieve----
$req = mysql_query('select password,id from users where username="'.$username.'"');
$dn = mysql_fetch_array($req);
if($dn['password']==md5($password) and mysql_num_rows($req)>0)
{ // ...
The reason you want to sanitize on retrieval is that most injections happen here. Case in point Facebook's hack from a user a year ago--he submitted a mysql_query retrieval into the browser to fetch another users data. And wound up inside the admin's program.
-
2The `mysql_*` functions should not be used in any new code for any reason. – Cat Feb 07 '13 at 00:01
-
1
-
-
-
2@showdev, no, bcrypt as provided by [`crypt`](http://php.net/crypt) in `$2y$` mode with a high cost. – Charles Feb 07 '13 at 00:11
-
1@user1938257, no. Validate and filter on input. SQL escape on insert. Optional escape on output depending on how you do filtering. [See previous answer](http://stackoverflow.com/a/3126175/168868). – Charles Feb 07 '13 at 00:11
-
May try sha512 too. Charles is right here. Many injections can use md5 which can be a threat. Use a $hash salt along with either one--$salt=fGMNIub43kJHb5T6kl; Then add it to all retrieved data etc . --$user=mysql_real_escape_string(sha1($_POST['password'] + $salt)) – Robin Dale Deatherage Feb 07 '13 at 01:12
-
1You do [SQL escaping](http://bobby-tables.com/php) on *any* and *all* things going into a query. You do HTML escaping on anything rendered in an HTML context. You **do not** use SQL escaping functions unless you're putting data into a database. Period. Your use of `stripslashes` here suggests this code only works in a recklessly misconfigured PHP environment. – tadman Feb 07 '13 at 01:43