DOM-based XSS
A DOM-based XSS is possible because an adversary-controlled inputs affect a so-called sensitive function. Examples of such functions are like: eval
, innerHTML
, setAttribute
, and document.write
.
Let us look at an example below. It is refactoring of our previous welcome application.
Here is the server side code:
const express = require('express');
const path = require("path");
let app = express();
// Function to handle the root path
app.get('/', async function(req, res) {
let username = req.query.username;
// Return the articles to the rendering engine
res.sendFile(path.join(__dirname, "main.html"));
});
let server = app.listen(8080, function() {
console.log('Server is listening on port 8080')
});
Here is the client-side code (note that for simplification, we ignored all other HTML parts):
<script>
var pos = document.URL.indexOf("username=") + 9;
document.write("hello! " + decodeURIComponent(document.URL.substring(pos,document.URL.length)));
</script>
Normally, we use the following URL to visit the page:
http://localhost:8080/?username=cao
However, if an adversary crafts an input like below, they can execute arbitrary scripts.
http://localhost:8080/?username=<script>alert(1)</script>
Note that there are many ways to craft XSS payload. Please find the following useful resources: XSS Cheat Sheet.