patternphpMinor
Preventing XSS attacks with proper escaping
Viewed 0 times
escapingwithxssattacksproperpreventing
Problem
The following page simulates XSS attacks and successfully (?) prevents them. I want to know if I've missed any other major attack vectors (or small ones) and/or if anyone has suggestions as to improving my escaping methods.
There are three contexts in which I attack:
To implement the solutions detailed above, I made three functions (2 in PHP, 1 in JS):
xss-attack-prevention.php:
xss-attack-prevention-helpers.php:
xss-attack-prevention-helpers.js:
```
function getType(val) { return Object.prototype.toString.call(val).slice(8, -1).toLowerCase(); }
function isString(val) { return getType(val) === "string"; }
function isArray(val) { return getType(val) === "array"; }
// returns false on unexpected input
// input must be
// - text : a string
// - repl
There are three contexts in which I attack:
- direct PHP echo into an HTML tag
- Attack: an HTML element with an onclick
- Solution: convert everything inside the tag into its HTML entity code
- inside a JavaScript string
- Attack: closing script tag followed by arbitrary code
- Solution: escape quotes as well as forward slashes
- setting innerHTML with JavaScript
- Attack: an HTML element with an onclick
- Solution: convert to HTML entities when setting innerHTML (unless it's supposed to be an element)
- inside an onclick attribute
- Attack: closing quote and adding another bit of code
- Solution: convert into HTML entities
To implement the solutions detailed above, I made three functions (2 in PHP, 1 in JS):
escapeForJSString: escapes anything that would break out of the string, as well as forward slashes, to prevent closing script tags
escapeHTMLSpecialChars: a wrapper aroundhtmlspecialcharsthat escapes single quotes
escapeForInnerHTML: basically does whathtmlspecialcharsdoes in PHP but in JS
xss-attack-prevention.php:
alert('y0uv3b33nh4ck3d');\"";
$userInput2 = "";
$userInput3 = "\"); alert(\"pwn3d!\\\")";
?>
XSS Attack Prevention
var n00bz = "";
var l33t = "";
")'
>Click me to see a message!
document.getElementById('div3').innerHTML = "Click me and nothing will happen!"
+ escapeForInnerHTML(l33t);
xss-attack-prevention-helpers.php:
xss-attack-prevention-helpers.js:
```
function getType(val) { return Object.prototype.toString.call(val).slice(8, -1).toLowerCase(); }
function isString(val) { return getType(val) === "string"; }
function isArray(val) { return getType(val) === "array"; }
// returns false on unexpected input
// input must be
// - text : a string
// - repl
Solution
There are already native functions to escape for HTML and JS strings:
As for
htmlspecialchars() and json_encode(). See this related question on Stack OverflowAs for
innerHTML, simply don't use it. Use textContent instead. If you wish to allow for formatting (for example, in comments or posts), I recommend MarkdownContext
StackExchange Code Review Q#71277, answer score: 2
Revisions (0)
No revisions yet.