XSS and path traversal · Cyber Security Basics
How can a comment box run code in other people's browsers?
Course contentsWhy you need it
Web apps constantly take text from one person and show it to others: comments, names, file names. If that text is treated as code or as a path, one visitor can attack every other visitor, or read files on your server. This lesson covers the two classic cases: cross-site scripting (XSS) and path traversal.
The intuition
A browser reads a page as HTML. If a comment contains <script>...</script> and you paste it into the page, the browser runs it, in every visitor's browser, with their login cookies.
The fix is to escape on output: turn < into < and > into >, so the browser shows the characters instead of obeying them. Python's html.escape does this.
File names have the same problem. ../ means "go up one folder", so ../../etc/passwd climbs out of your upload folder. Normalise the path (resolve every ..) and then check it still starts inside the allowed folder.
In both cases, prefer an allow-list (accept only what you expect) over a block-list (reject what you've thought of).
Definition
Cross-site scripting (XSS)
An attack where text supplied by a user is shown as HTML, so a script inside it runs in other users' browsers.
Path traversal
An attack where a file name such as `../../secret` makes a program open a file outside the folder it meant to use.
Examples
Escape on output
Try it yourselfThe first line is what a careless page would contain; the second is safe to put in HTML.
import html
comment = '<script>steal(document.cookie)</script>'
print("<p>" + comment + "</p>")
print("<p>" + html.escape(comment) + "</p>")
print(html.escape('Tom & "Jerry"'))- L3Pasted as-is: a browser would run steal(...).
- L4Escaped: the browser shows the text and runs nothing.
- L5
&and quotes are escaped too, so attributes are safe.
Climbing out of a folder
Try it yourselfos.path.normpath resolves every ... Then we check the result is still inside BASE.
import os
BASE = "/srv/files"
def resolve(name):
return os.path.normpath(os.path.join(BASE, name))
for name in ["report.pdf", "../../etc/passwd", "img/../logo.png"]:
path = resolve(name)
print(path, path.startswith(BASE + "/"))- L5Join the folder and the name, then resolve the dots.
- L9A normal file stays inside: True.
/srv/files/report.pdf True - L9
../../climbs to the top: the check catches it./etc/passwd False - L9
..that stays inside is fine./srv/files/logo.png True
Common mistakes
Block-lists
Removing <script> isn't enough: <img src=x onerror=...> runs code too, and so do many other tags. Escape everything on output instead of hunting for dangerous words.
A prefix check without the slash
path.startswith("/srv/files") also accepts /srv/files_backup/secret. Check for the folder plus /.
Quick quiz
1. What does this print?
import html
print(html.escape("<b>hi</b>"))Show the answer
Answer: A
Every < becomes < and every > becomes >. A browser shows that as the literal text <b>hi</b>.
2. A sign-up form asks for a username. Which rule is an allow-list?
Show the answer
Answer: B
An allow-list describes exactly what is accepted. Everything else, including attacks nobody thought of, is rejected.
Practice
3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.
- PredictWhere does it point?
Type exactly what this program prints.
- ModifyEscape the comment
render(name, text)builds the HTML for one comment by pasting both values in. Change it so both the name and the text are escaped withhtml.escape. - WriteSafe file paths
Write
safe_path(name)for a download page. JoinnameontoBASE, normalise it, and:- return the full path if it is inside
BASE(it starts withBASE + "/") - otherwise return
None
- return the full path if it is inside
Practise this lesson
Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.
Interactive lessons open in order. If you have not done the earlier ones yet, you start at the course map.
Terms in this lesson
| Term | Chinese | Definition |
|---|---|---|
| Cross-site scripting (XSS) | 跨站脚本(XSS) | Running an attacker's script in other users' browsers through unescaped text. |
| Escaping | 转义 | Replacing special characters such as < with safe codes such as <. |
| Path traversal | 路径穿越 | Using ../ in a file name to reach files outside the intended folder. |
| Normalise a path | 规范化路径 | Resolve . and .. so the path shows where it really points. |