The JavaScript utility functions used on this page, in particular the URLSearchParams interface, might not work in all browsers: see
the list of browsers that support it.
The fragment of HTML below uses JavaScript in combination with
the DOM to retrieve the parameter name from the
URL to include include it in the content of the page. If you
change the value
of the parameter name, say from
'John' to 'Maria', the webpage show change.
Hello
!
Welcome to this webpage.
You can now try to inject HTML mark-up tags, or even scripts, in
the parameter name.
For instance, try the links below:
Alter the URL to change the effect of the script.
Or see if you enter a name followed by a script, or
multiple scripts.
To try out some fancier JavaScript features: try to make a malicious URL that triggers a DOM-based XSS which opens a new tab in the victim's browser, and try to see if you can open multiple new tabs.
See demo_DOM or DOM exercise for example JavaScript that will open new tabs.
Send yourself an email with one of these XSS links, and see if your
email client strips suspicious scripts from URLs
inside emails when you click them.
If it does, you could try to use a URL-shortener,
such as https://tinyurl.com,
to create a abbreviated URL will hide any script tags
from the email client. This will also prevent people
from seeing the suspicious script tags inside the link
before they click on it.
Note that the DOM-based cross-site scripting on this page is
no threat to our web server: you are simply injecting
JavaScript that you are running client-side in your own
browser. The script is sent to the server, but the server
does nothing with it: the server just returns a fixed HTML
page, and it is only when your browser renders this page, and
executes the JavaScript inside, that the payload in the
name parameter fires.
The defence against reflected XSS that used to be built-in
browsers, as XSS Filter in Edge and XSS auditor in Chrome,
would strip any scripts from a webpage that are
identical to scripts passed as parameters in the
URL. These defences have been retired in 2018 and 2019.
(If you have a really old Edge or Chrome browser, you could try
this out if it helps here.)
This defence might stop some classic reflected XSS, but it
would probably not stop this DOM-based XSS: after all, the
script here is not included in the HTML page returned by the
server. It is only when the JavaScript code start executing
that the malicious scripts are inserted inside the webpage.
A typical XXS injection via the DOM will not be so simple as
on this page:
An attacker may have to explore many ways to provide malicious
inputs, in various places, before getting lucky and
discovering a path by which input can end up inside JavaScript
code that gets executed. Here malicious input can
not just be provided in URL parameters, as in the case of
this page, but also in inputs submitted to the server
earlier, say when registering a user name.
The path through which execution of the payload happens may
involve multiple function calls in JavaScript,
and the attack script may have to be tailored to this
exact path. It may even
require multiple malicious inputs, each supplying a fragment of the
attack script.
If the attacker's inputs are passed back and forth between
client and server they may end up being being HTML- or
ULR-decoded, which may prevent them from triggering as
scripts. In fact, for this page, the name
parameter in the URL is URL-encoded. Normally this would
prevent it from being executable JavaScript, as
<script> URL-encodes to
%3Cscript%3E. However, the JavaScript library
function we use to retrieve the parameter values (the
function get of the class
URLSearchParams) is kind enough to automatically
URL-decode data for us ;-)
If the JavaScript inside this webpage would
(re-)URLencode the parameters before inserting them
in the HTML then a simple DOM-based XSS is no longer
possible. For instance, the URL-encoded name in
the current URL displays as
.