0 / 7
Stored XSS
The attacker writes a script into a message board and wants it to run in the browser of a victim who opens that post later. This kind of attack, inserting a script into a web page so it runs in someone else's browser, is XSS. The three types differ in who inserts that script. In stored XSS, the server takes it from a saved post and inserts it.
Example: The attacker posts a message containing a script, and the victim opens that post later.
Who inserts the script: the server (from the saved post)
1 / 7
Attacker: post a message with a script
The attacker writes a script that steals cookies into the content of a post. The server accepts it only as post content, not as code.
2 / 7
Server: save the post
The server saves the post as it is without checking the content. The script is now stored on the server, but no one has been harmed yet.
3 / 7
Victim: open the post
The victim asks the server to open the post, just as usual. The victim did nothing wrong.
4 / 7
Server: insert the saved post into the page
The server builds the post page anew on every request. It inserts the saved post as it is into the basic page template (HTML) it will send to the victim. That post contains the attacker's script, so the built page contains the script too. The one who inserts the script is the server.
5 / 7
Server → victim: send the page
The server sends the finished page to the victim. The page contains the script.
6 / 7
Victim's browser: run the script
When the victim's browser meets the script in the page, it runs it. It cannot tell who put the script there. Because the code is in a page sent by the site, it runs with the site's own permissions and can read the cookie too.
7 / 7
Victim → attacker: send the cookie
The script sends the victim's cookie to the attacker. The attacker uses that cookie to log in pretending to be the victim. The same thing happens to everyone who opens that post.
1 / 7
Attacker: make a malicious link
The attacker writes a script in the search word part of a search address to make a link. It is not saved on the server; it is carried inside the link.
2 / 7
Attacker → victim: send the link
The attacker sends the link to the victim by email or a messenger. Shortening the address or rewriting its characters makes the script hard to notice.
3 / 7
Victim: click the link
When the victim clicks the link, the browser sends a search request to the server. The search word in the request contains the script.
4 / 7
Server: insert the search word into the page
The results page is also built anew by the server on every request. The server inserts the search word from the request as it is into the page template it will send to the victim. That search word contains the attacker's script, so the built page contains the script too. The request comes straight back in the response, which is why it is called reflected. The one who inserts the script is the server.
5 / 7
Server → victim: send the page
The server sends the results page to the victim. The page contains the script. The server does not keep this search word and uses it only in the response.
6 / 7
Victim's browser: run the script
The victim's browser runs the script in the results page. Because the site sent the page, the script can read the victim's cookie too.
7 / 7
Victim → attacker: send the cookie
The script sends the victim's cookie to the attacker. Unlike stored XSS, this happens only to the person who clicked the link.
1 / 7
Attacker: make a malicious link
The attacker writes a script after the # at the end of the site address to make a link.
2 / 7
Attacker → victim: send the link
The attacker sends the link to the victim by email or a messenger.
3 / 7
Victim: click the link
When the victim clicks the link, the browser asks the server for the page. The browser does not send the part after # to the server. So the server never even learns that a script exists.
4 / 7
Server → victim: send the usual page
The server sends the page it always sends. There is no script in it. The script is after the #, which never reaches the server, so no matter how carefully the server checks input, it cannot stop this attack.
5 / 7
Victim's browser: insert the address text into the page
The page the server sent has already arrived and is open in the victim's browser. JavaScript that was already in it reads the text after # in the address and inserts it into the page. That text contains the attacker's script, so the open page now contains the script too. The one who inserts the script is not the server but the browser. This is exactly where it differs from reflected XSS.
6 / 7
Victim's browser: run the script
The browser runs the inserted script. The script never passed through the server. It went straight from the address into the page in the victim's browser.
7 / 7
Victim → attacker: send the cookie
The script sends the victim's cookie to the attacker. The server's request log does not contain the part after #.
1 / 6
Attacker: post the same post
The attacker posts exactly the same post as in stored XSS. The content contains a script that steals cookies.
2 / 6
Server: save the post
The server saves the post as it is. Because the post only goes into pages as text here, a stored script does no harm. The key step is changing characters when the post is put into a page, not when it is saved.
3 / 6
Victim: open the post
The victim asks the server to open the post, just as usual.
4 / 6
Server: change characters and insert into the page
Before inserting the saved post into the page template it will send to the victim, the server changes < to < and > to >. So <script> in the post becomes <script>. The server still inserts it, but now it inserts text, not code.
5 / 6
Server → victim: send the page
The server sends the page to the victim. The page holds the text <script>, not <script>.
6 / 6
Victim's browser: show as text
The victim's browser shows < on the screen as the < character, not as the start of code. The script does not run. The code just appears as text in the post. The cookie does not reach the attacker.