<script>..</script><img .. /><script> or loaded externally<script>...</script><img onerror="..." src="x"><svg/>document.write()fetch()What is an origin?
http://www.website.com:80
origin = scheme + host + port
What is a site?
http://www.website.com:80 > https://mobile.website.com:443 > ftp://f.website.com:21
site = private_domain + public_suffix
http://www.website.com:80
origin = scheme + host + port
site = private_domain + public_suffix site = domain
The payload is part of a HTTP request, that is injected in the immediate HTTP response.
The payload is stored serverside (e.g. file or database).
Typically more dangerous than reflected. Anyone who opens a page that returns content from that same database may be victim to a stored XSS attack.
The client pieces together data which eventually becomes an exploit itself.
i.e.
document.write(...)
Don’t use .innerHTML or .outerHTML
use .innerText or .textContent
Demo: DOM XSS
JS Frameworks
X-XSS-Protectionheader
Turn it off, it’s broken 🔥 🌊🚒
✅ X-XSS-Protection: 0
“Firefox never supported X-XSS-Protection and Chrome and Edge have announced they
are droppinghave dropped support for it."
Sandboxing
iframes, sandbox, seamless, etc…
Link: GitHub
Cross site request forgery
Tricking a user into making requests they didn’t intend, sending data and loading attacker controlled documents
Stop CSRF attempts by supplying the user with a single-use ’nonce’ value.
Can’t forge a request if you don’t know the nonce before hand… sort of…
CSRF vs XSS
Generally XSS is performed in the background (since it’s a script exploit)
eval()https://app.example.com/https://api.example.com/Preflight response headers (repsonse to an OPTIONS request to https://api.example.com/):
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization, X-Request-ID
Access-Control-Max-Age: 600
Vary: Origin
Response to actual request (e.g. PUT,POST)
Content-Type: application/json
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: X-Request-ID, X-RateLimit-Remaining
Vary: Origin