Cross Site Scripting (XSS)
Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted web sites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.
An attacker can use XSS to send a malicious script to an unsuspecting user. The end user’s browser has no way to know that the script should not be trusted, and will execute the script. Because it thinks the script came from a trusted source, the malicious script can access any cookies, session tokens, or other sensitive information retained by the browser and used with that site. These scripts can even rewrite the content of the HTML page.[1]
Challenges covered in this chapter
Name | Description | Difficulty |
---|---|---|
API-only XSS |
Perform a persisted XSS attack with |
⭐⭐⭐ |
Bonus Payload |
Use the bonus payload |
⭐ |
Client-side XSS Protection |
Perform a persisted XSS attack with |
⭐⭐⭐ |
CSP Bypass |
Bypass the Content Security Policy and perform an XSS attack with |
⭐⭐⭐⭐ |
DOM XSS |
Perform a DOM XSS attack with |
⭐ |
HTTP-Header XSS |
Perform a persisted XSS attack with |
⭐⭐⭐⭐ |
Reflected XSS |
Perform a reflected XSS attack with |
⭐⭐ |
Server-side XSS Protection |
Perform a persisted XSS attack with |
⭐⭐⭐⭐ |
Video XSS |
Embed an XSS payload |
⭐⭐⭐⭐⭐⭐ |
Perform a persisted XSS attack without using the frontend application at all
As presented in the
Architecture Overview, the OWASP Juice
Shop uses a JavaScript client on top of a RESTful API on the server
side. Even without giving this fact away in the introduction chapter,
you would have quickly figured this out looking at their interaction
happening on the network. Most actions on the UI result in
XMLHttpRequest
(XHR
) objects being sent and responded to by the
server.
For the XSS Tier 3 challenge it is necessary to work with the
server-side API directly. You will need a command line tool like curl
or a
tool for HTTP request tampering
to master this challenge.
-
A matrix of known data entities and their supported HTTP verbs through the API can help you here
-
Careless developers might have exposed API methods that the client does not even need
Use the bonus payload in the DOM XSS challenge
The underlying vulnerability of this challenge is the same as for the Perform a DOM XSS attack challenge. The effect of the payload is much more entertaining, though.
-
First, solve the Perform a DOM XSS attack challenge
-
Now it is just a question of copying and pasting the payload into the same vulnerable field
-
Crank up the volume of your computer before submitting the payload! 🔊
Bypass the Content Security Policy and perform an XSS attack on a legacy page
In the Architecture overview you were told that the Juice Shop uses a modern Single Page Application frontend. That was not entirely true.
-
Find a screen in the application that looks subtly odd and dated compared with all other screens
-
Before trying any XSS attacks, you should understand how the page is setting its Content Security Policy
-
For the subsequent XSS, make good use of the flaws in the homegrown sanitization based on a RegEx!
Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement to distribution of malware.
CSP is designed to be fully backward compatible ([…]). Browsers that don’t support it still work with servers that implement it, and vice-versa: browsers that don’t support CSP simply ignore it, functioning as usual, defaulting to the standard same-origin policy for web content. If the site doesn’t offer the CSP header, browsers likewise use the standard same-origin policy.
To enable CSP, you need to configure your web server to return the Content-Security-Policy HTTP header ([…]).[2]
Perform a persisted XSS attack bypassing a client-side security mechanism
This challenge is founded on a very common security flaw of web applications, where the developers ignored the following golden rule of input validation:
Be aware that any JavaScript input validation performed on the client can be bypassed by an attacker that disables JavaScript or uses a Web Proxy. Ensure that any input validation performed on the client is also performed on the server.[3]
-
There are only some input fields in the Juice Shop forms that validate their input.
-
Even less of these fields are persisted in a way where their content is shown on another screen.
-
Bypassing client-side security can typically be done by
-
either disabling it on the client (i.e. in the browser by manipulating the DOM tree)
-
or by ignoring it completely and interacting with the backend instead.
-
Perform a DOM XSS attack
DOM-based Cross-Site Scripting is the de-facto name for XSS bugs which are the result of active browser-side content on a page, typically JavaScript, obtaining user input and then doing something unsafe with it which leads to execution of injected code.
The DOM, or Document Object Model, is the structural format used to represent documents in a browser. The DOM enables dynamic scripts such as JavaScript to reference components of the document such as a form field or a session cookie. The DOM is also used by the browser for security - for example to limit scripts on different domains from obtaining session cookies for other domains. A DOM-based XSS vulnerability may occur when active content, such as a JavaScript function, is modified by a specially crafted request such that a DOM element that can be controlled by an attacker.[4]
-
This challenge is almost indistinguishable from Perform a reflected XSS attack if you do not look "under the hood" to find out what the application actually does with the user input
Perform a persisted XSS attack through an HTTP header
This XSS challenge originates from an unsafely processed user input via an HTTP header. The difficulty lies in finding the attack path whereas the actual exploit is rather business as usual.
-
Finding a piece of information displayed in the UI that could originate from an HTTP header
-
You might have to look into less common or even proprietary HTTP headers to find the leverage point
-
Adding insult to injury, the HTTP header you need will never be sent by the application on its own
Perform a reflected XSS attack
Reflected Cross-site Scripting (XSS) occur when an attacker injects browser executable code within a single HTTP response. The injected attack is not stored within the application itself; it is non-persistent and only impacts users who open a maliciously crafted link or third-party web page. The attack string is included as part of the crafted URI or HTTP parameters, improperly processed by the application, and returned to the victim.[5]
-
Look for a URL parameter where its value appears on the page it is leading to
-
Try probing for XSS vulnerabilities by submitting text wrapped in an HTML tag which is easy to spot on screen, e.g.
<h1>
or<strike>
.
Perform a persisted XSS attack bypassing a server-side security mechanism
This is one of the hardest XSS challenges, as it cannot be solved by just fiddling with the client-side JavaScript or bypassing the client entirely. Whenever there is a server-side validation or input processing involved, you should investigate how it works. Finding out implementation details e.g. used libraries, modules or algorithms - should be your priority. If the application does not leak this kind of details, you can still go for a blind approach by testing lots and lots of different attack payloads and check the reaction of the application.
When you actually understand a security mechanism you have a lot higher chance to beat or trick it somehow, than by using a trial and error approach.
-
The Comment field in the Contact Us screen is where you want to put your focus on
-
The attack payload
<iframe src="javascript:alert(`xss
)">` will not be rejected by any validator but stripped from the comment before persisting it -
Look for possible dependencies related to input processing in the
package.json.bak
you harvested earlier -
If an
xss
alert shows up but the challenge does not appear as solved on the Score Board, you might not have managed to put the exact attack string<iframe src="javascript:alert(`xss
)">` into the database?
Embed an XSS payload into our promo video
As with the previous one, the difficulty of this challenge is based on how hard it is to successfully place the XSS payload in the application.
-
Without utilizing the vulnerability behind another ⭐⭐⭐⭐⭐⭐ challenge it is not possible to plant the XSS payload for this challenge
-
The mentioned "marketing collateral" might have been publicly advertised by the Juice Shop but is not necessarily part of its sitemap yet
-
It might help to perform some online searches for structurally similar web projects once you get stuck.
-
This challenge will always partially keep you blindfolded, no matter how hard you do research and analysis.