2

I've read that it's enough and even recommended to escape characters on the output, not on the input.

It could be easily applied to all get variables as they are not injected to the database from the form level.

However, I'm not sure what to do with all post variables. If it doesn't come from the database, so if it's a raw input data, escaping is fully needed. But I'm using PDO prepare/execute to escape all variables. Questions now:

  1. Is it OK to use PDO's prepare/execute both in select and insert statements? Isn't it escaping variables twice ?
  2. Let's say I get some variable through PDO exeute statement - is it ok to display this variable simply with $_POST['variable'] without escaping it (if it was already done in PDO function) ?
  3. Is htmlspecialchars() enough to escape things such as GET variables which don't come from the database?

And the most important - is all of this, PDO prepare/execute, and htmlspecialchars(), enough to prevent all XSS attacks? Or should I also do more? If so, what should this be? Removing all html tags from the input? Using BB-Code instead?

j08691
  • 204,283
  • 31
  • 260
  • 272
user1615069
  • 631
  • 4
  • 16
  • 26
  • Not sure what you mean by _Get some variable through PDO execute statement and display this variable simply with $_POST['var']_, but just keep on using prepared statements, and don't worry about this _"escaping"_ chars twice or more... that's not what happens. And _never_ think things like `htmlspecialchars` is enough, because it isn't, it-just-is-not-enough. – Elias Van Ootegem Nov 02 '12 at 16:21
  • on point 2. what if the variable didn't come from database, ie confirmation page before DB insert? – Waygood Nov 02 '12 at 16:21

4 Answers4

9

I've read that it's enough and even recommended to escape characters on the output, not on the input.

Typically, you want to:

  • Validate input and store it using prepared statements. Prepared statements will protect your database against SQL injections. Typically, you don't want to strip out HTML tags on input because doing so could lead to a loss of data integrity.
  • When displaying user-generated data (output), you can guard against XSS by using a combination of htmlentities and mb_convert_encoding.

Note on the htmlspecialchars function from another question:

Even if you use htmlspecialchars($string) outside of HTML tags, you are still vulnerable to multi-byte charset attack vectors.

The most effective you can be is to use the a combination of mb_convert_encoding and htmlentities as follows.

$str = mb_convert_encoding($str, ‘UTF-8′, ‘UTF-8′);
$str = htmlentities($str, ENT_QUOTES, ‘UTF-8′);
Community
  • 1
  • 1
Wayne Whitty
  • 19,513
  • 7
  • 44
  • 66
  • +1 At least if you sanitize output and there is a mistake in your sanitization process, you can correct it. If you sanitize before storage, there's no going back, the original is destroyed. – Waygood Nov 02 '12 at 16:25
2

escape characters on the output, not on the input

Yes.

easily applied to all get variables

But $_GET is by definition input

Isn't it escaping variables twice ?

No - by escaping the content you're just insulating it from mis-interpretation by the processing agent. The database doesn't store the escaped data, it stores the original data.

Hence if start with

O'Reilly

Then escape to splice it into a SQL string....

O\'Reilly

Then the value stored in the database, and retrieved by a SELECT statement is

O'Reilly

And when you want to output it your HTML, then you pass it though htmlspecialchars() to get

O"Reilly

You use an appropriate method for escaping the data depending on where it's going - hence you use mysql_real_escape() or paramter binding or similar when putting stuff INTO your database, and htmlspecialchars() when putting stuff INTO html

symcbean
  • 47,736
  • 6
  • 59
  • 94
1
  1. whenever data is coming from user, sanitize it(take special attention if its storing in database.). So PDO with prepared statement is a must. What else you do is added bonus.

  2. Yes (opinions will differ here from person to person) for preventing sql injection (assuming you are using prepared statement). though I prefer storing the raw data in database even if it means sacrificing for some malicious XSS code may contain it. While outputting, take utmost care.

  3. No. use htmlpurifier (with a view that you are outputting from a database.)

itachi
  • 6,323
  • 3
  • 30
  • 40
0

I use mysqli_real_escape_string and preg_replace

$email = mysqli_real_escape_string($dbc, trim($_POST['email']));
$password = mysqli_real_escape_string($dbc, trim($_POST['password']));
$domain = preg_replace('/^[a-zA-Z0-9][a-zA-Z0-9\._\-&!?=#]*@/', '', $email);

Also, here is a link to a similar post regarding PDO escaping Escape arguments for PDO statements?

Community
  • 1
  • 1
Alex
  • 542
  • 5
  • 24
  • 1
    You shouldn't be validating emails with regex and why would you need mysqli_real_escape_string if you're using prepared statements. – Wayne Whitty Nov 02 '12 at 16:22
  • I'm sure my Foreign visitors wouldn't mind you chopping their name off LOL – Waygood Nov 02 '12 at 16:22
  • I should have explained what I was doing with the preg_replace instead of just trying to provide some basic example. I use the preg_replace to check if the domain is legit. – Alex Nov 02 '12 at 16:28
  • I'm sure Pelé would be very happy as he has email address of Pelé@黒川.日本 – Waygood Nov 02 '12 at 16:31
  • very good point! thank you, I'll need to make modifications of my own now! – Alex Nov 02 '12 at 16:35