Recently, when reviewing the interim findings of a pen test of a third party's system I noticed an odd comment from the tester which suggested they were struggling with XSS injection. Something was interfering with the reflection of the injected scripts, and it wasn't encoding which was responsible.
Called up the third party to ask what validation they were using. Dev didn't even know about input validation. Huh.
So, what was going on? < and it's non identical twin, > were being stripped, along with everything inside them. Chatting further with the dev, we found the evil strings were in the database, so something was indeed stopping the attack strings getting reflected into the DOM where they would have executed.
Stripping characters isn't a great way (again, British, understatement...) to defeat XSS, and stripping just <> is likely to leave you open to a whole world of evasion techniques, but what was doing it?
Taking a look at the DOM and the requests the browser was making, it became clear jQuery was responsible for taking content from the database via some php and passing it to the client. So... does jQuery strip anything from elements?
Yep, jQuery will strip < and > from an element, unless you tell it otherwise. (Version 1.12.1):
// Handle HTML strings
if ( typeof selector === "string" ) {
if ( selector.charAt( 0 ) === "<" &&
selector.charAt( selector.length - 1 ) === ">" &&
selector.length >= 3 ) {
Called up the third party to ask what validation they were using. Dev didn't even know about input validation. Huh.
So, what was going on? < and it's non identical twin, > were being stripped, along with everything inside them. Chatting further with the dev, we found the evil strings were in the database, so something was indeed stopping the attack strings getting reflected into the DOM where they would have executed.
Stripping characters isn't a great way (again, British, understatement...) to defeat XSS, and stripping just <> is likely to leave you open to a whole world of evasion techniques, but what was doing it?
Taking a look at the DOM and the requests the browser was making, it became clear jQuery was responsible for taking content from the database via some php and passing it to the client. So... does jQuery strip anything from elements?
Yep, jQuery will strip < and > from an element, unless you tell it otherwise. (Version 1.12.1):
// Handle HTML strings
if ( typeof selector === "string" ) {
if ( selector.charAt( 0 ) === "<" &&
selector.charAt( selector.length - 1 ) === ">" &&
selector.length >= 3 ) {
Risky? You betcha!* Consider:
1. Your application is only "safe" from XSS because two characters are filtered out when the strings are passed to the DOM. This won't protect you from clever encoding (JSF*ck?), reflecting the string back in CSS or js...
2. Your one protection is based in a script which you don't own. One change, intentional or otherwise could remove this protection.
3. The attack strings exist in your database. What if someone or something else uses your data?**
Escape, validate and encode, people.
**https://github.com/Netflix/sleepy-puppy Check this out, stored and latent XSS detection like a boss.
Comments
Post a Comment