I'm newish to PHP but I hear XSS exploits are bad. I know what they are, but how do I protect my sites?
safe2() is clearly
In place of
safe1() you should really be using
htmlspecialchars(strip_tags($src)) would actually work fine.
safe3() screams regular expression. Here you can really only apply a whitelist to whatever you actually want:
var a = "<?php echo preg_replace('/[^-wd .,]/', "", $xss)?>";
You can of course use
json_encode here to get a perfectly valid JS syntax and variable. But then you've just delayed the exploitability of that string into your JS code, where you then have to babysit it.
Is it also safe in all browsers (specifically IE6)?
If you specify the charset explicitly, then IE won't do its awful content detection magic, so UTF7 exploits can be ignored.
htmlspecialchars() is enough to prevent document-creation-time HTML injection with the limitations you state (ie no injection into tag content/unquoted attribute).
However there are other kinds of injection that can lead to XSS and:
There are no <script> tags in the document.
this condition doesn't cover all cases of JS injection. You might for example have an event handler attribute (requires JS-escaping inside HTML-escaping):
<div onmouseover="alert('<?php echo htmlspecialchars($xss) ?>')"> // bad!
It is usually best to avoid these constructs anyway, but especially when templating. Writing
<?php echo htmlspecialchars(urlencode(json_encode($something))) ?> is quite tedious.
And... injection issues can happen on the client-side as well (DOM XSS);
.html() in poor jQuery scripts) without explicit escaping.
And... XSS has a wider range of causes than just injections. Other common causes are:
allowing the user to create links, without checking for known-good URL schemes (
deliberately allowing the user to create markup, either directly or through light-markup schemes (like bbcode which is invariably exploitable)
allowing the user to upload files (which can through various means be reinterpreted as HTML or XML)
The misconception is that you want to escape the input, which is wrong. You have to filter the output (and database is also an output).
It means that when the form is submitted, you use
mysql_real_escape_string() to send (output) data to database, and you use
htmlspecialchars() to output the content on the screen. The same principle applies to regular expressions, where you'd use
preg_quote(), and so on.
No matter where data is coming from, you have to escape it in the context of where you are sending it to.
So for preventing XSS attacks, you must use
mysql_real_escape_string has nothing to do with XSS (but you still have to use it when you are sending data to the database).
As mentioned, prepared statements are one of the best ways to prevent SQL injections. i.e., you shouldn't add your parameters as part of the final query string. You should use parameter placeholders, and add the parameters via a key/value array.
If you're using PDO, have a look at this page, which describes prepared statements in greater detail:
A quite thorough explanation of PHP's input filters (and a good article on sanitization) can be found here:
Check here for PHP's own filters/sanitization functions:
You are probably interested in the filter_var and filter_input functions:
Also, this question has some good pointers: What's the best method for sanitizing user input with PHP?
This question has very good pointers too: What are the best PHP input sanitizing functions?