Bad news
Unfortunately, preventing XSS in PHP is a nontrivial undertaking.
Unlike SQL injection , which you can soften using prepared statements and carefully selected white lists, there is no reliable way to separate the information you are trying to transfer your HTML document from the rest of the document structure.
Good news
However, you can mitigate known attack vectors, especially for fear of your shielding ( and updating your software up to date ).
The most important rule to keep in mind: Always exit at the exit, never at the entrance. You can safely cache your shielded output if you are concerned about performance, but always save and manage unescaped data.
XSS Reduction Strategies
In order of preference:
- If you use a template engine (e.g. Twig, Smarty, Blade), make sure it offers context-sensitive escaping. I know from experience what Twig does.
{{ var|e('html_attr') }} - If you want to enable HTML, use the HTML Cleaner . Even if you think that you accept only Markdown or ReStructuredText, you still want to clear HTML these markup languages.
- Otherwise, use
htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset) and make sure that the rest of the document uses the same character set as $charset . In most cases, 'UTF-8' is the desired character set.
Why shouldn't I filter the input?
Attempting to filter XSS in the input for premature optimization , which can lead to unexpected vulnerabilities in other places.
For example, a recent WordPress XSS vulnerability used MySQL column truncation to break their escaping strategy and allow insecurely to prevent premature payload leakage. Do not repeat your mistake.
Scott Arciszewski
source share