Cross Site scripting
This is a vulnerability that allows an attacker to compromise the interactions that the users have with the vulnerable application by somehow being able to inject javascript into the vulnerable application which returns this malicious javascript to users. This script executes in the user's browser in context of that user's session with the application. It allows an attacker to cricumvent same origin policy(a script contained in first web page is able to access data in second web page if both pages have same origin protocal port and host are same). This vulnerability normally allows an attacker to masquerade as a victim user and carry out any actions that the victim user is able to perform. There are three types of xss they are
Reflected xss: Where the malicious script comes from the current http request.
Stored xss: Where the malicious script comes from website's database
DOM xss: Where the vulnerability exists in client side code rather than server side code.
Note: Use print()
function instead of alert()
in chrome. NOte: Always utilize dev tools console for creating xss payloads that performs certain/different actions. Cheatsheet:: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
Leveraging Cross Site Scripting
Stealing Cookies
We can steal cookies by injecting javascript which sends the vicim's cookies to our own domain. Limitations include the victim might not be logged into the application, the application hides its cookies from javascript using
HttpOnly
flag, session might time out before we are able to hijack it. Using XMLHttpRequest
Using fetch
Stealing password if password manager is used
If the victim user is using any kind of password manager which auto fills password, we can create same password input field then read the auto filled password and send it to our own domain. Here not only javascript between script tags is possible but html tags can also be injected with events.
XSS to perform CSRF attack
XSS can be used to perform csrf attack as follows to change email address of victim.
How to Test for Reflected, Stored XSS ?
Submit a simple Input into every entry point in the application eg: url paremeters, form inputs, headers, hidden fields, file upload names, anything.
Now identify the context of the displayed(reflected or stored ) data whether its simply displayed inside html tags like <p>, <body>, etc or the data is displayed within html tag's attributes like src or href or inside javascript variable values, etc Always identify the context of the reflected or stored data.
Now use below cheatsheet to craft a suitable payload based on the context
XSS in different contexts
The location of reflected or stored data within the application's response determines what type of payload is required to exploit it and might also affect the impact of the vulnerability. In addition if the application performs any kind of validation on the reflected data we need to come up with bypass ideas.
When testing for reflected or stored xss a key task is to identify the xss context.
The location within the response where the attacker controllable data appears.
Any input validation or other processing that is being performed on the data by the application.
Simple xss between html tags
If all tags are blocked we can use custom tags and trigger javascript via onfocus attribute. Below is a custom tag with
id=x
when focus is on this element javascript function alert() is called, heretabindex=1
tabindex is global attribute which allows an element to receive focus, this ensures onfocus event is triggered when user navigates to this element and finally#x
is anchor link or fragment which targets this element.
<xss id=x onfocus=alert(document.cookie) tabindex=1>#x
Indirectly calling alert function using svg, anchor and animate tag
Fires when svg animation begins
<svg><animatetransform onbegin=alert(1) attributeName=transform></svg>
. All these can be found in https://portswigger.net/web-security/cross-site-scripting/cheat-sheet.
XSS in HTML tag's attributes
When xss context is in html tag attribute's value we might be able to terminate the attribute value using
"
close the tag using>
and induce a new tag like"><script>alert(document.cookie)</xss>script>
If angle brackets are blocked and we can only terminate the attribute's value and create a new attribute like an event listener to introduce javascript code.
If the xss context is in href attribute like
<a href="$_GET['search']"></a>
we can simply use javascript pseudo protocal to execute script.
If xss is in href attribute of canonical tag
<link rel="canonical" href='https://0aa700c904d7a10e80a00897001a0090.web-security-academy.net/' />
and we are able to close the attribute using single or double quotes we can introduce accesskey and onclick attribute when pressed a key combintaion fires the event?'accesskey='x'onclick='alert(1)
XSS inside javascript
When xss context is some existing javascript within the response wide variety of techniques can be leveraged.
If the xss context is inside some variable in the javascript we can simply close the script tag and and introduce new html tag with some event to trigger xss. Here we donot need to close the variable using
'
single quotes simpy we can do</script><img src=1 onerror=alert("test")>
If we cannot introduce new tags due to angle brackets blocked we can simply close the string literal and introduce any javascript code and comment out rest of the code.
'; alert("hello") //
or'-alert(document.domain)-'
Some application escapes the single quote itself using backslash so that user cannot break of the javascript string but fails to escape the backslash character itself so an attacker can add a backslash character itself to neutralize the backslash added by the application.
If xss context is some existing javascript like event handlers inside html tag attribute and single quote is filtered we can use HTML-encoding to bypass this because after the browser has parsed html tags and attributes within a response it will perform HTML decoding of tag attribute's values before they are processed any further so we can utilize html encoding to bypass filters. Context
Payload
becomes
If the xss context is javascript template literal like this
we can use embedded expression and exeute malicious javascript by using ${...}
syntax
How to test for Stored Cross Site Scripting
To find stored xss vulnerabilties we need to
test all entry points via which attacker controlled data can enter into the application and all exit points at which the data might appear in the application's response.
The entry points include url parameters, post/get request data, out of band routes like data received via emails, displaying data contained in third party tweets, news aggregator will include data originating on other web sites. Exit points can be anywhere within the application.
Now identify the context of the stored input like in between html tags, within html tag's attributes, javascript variable's value, etc
Based on the context use the above cheatsheet to craft a suitable payload.
DOM based cross site scripting(Use inspect element to identify sink)
The browser's view source won't work for DOM xss testing. It is a cross site scripting context which occurs when an application contains some client side javascript that takes data from an attacker controlled source such as URL and passes it to a sink that supports dynamic code execution such as eval()
or innerHTML
. for example
If the attacker can control the value of the input field he can easily construct a malicious value that causes their own script to execute <img src=x onerror='/*Bad Stuff Here*/' />
Testing for DOM based xss can be little difficult because our input may not necessarily appear anywhere in the DOM. There are two types of DOM xss
DOM xss in HTML sinks
DOM xss in javascript sinks
DOM xss in HTML Sinks
TO test for dom xss in HTML sink we need to place a random alphanumeric string into source such as location.search
and use developer tool to inspect the HTML and find where our input appears. Now we need to identify the context and refine our payload eg: if our input appears within double quotes attribute we can use double quotes to break out of the attribute.
DOM XSS in Javascript sinks
This is little harder because our input does not appears anywhere within the DOM so we can't search for it instead we need to use javascript debugger to determine whether and how our input is sent to a sink. For each potential source such as location
we need to identify in the javascript source code where this source is referenced once we found where the soure is being red we can use javascript debugger to add a breakpoint and and follow how the source value is used.
How to Test for DOM xss
We need to read the javascript source code to identify DOM xss
DOM xss in document.write
sink via location.search
source
document.write
sink via location.search
sourceHere, the search query is taken from url and passed to document.write
sink. Although our input doesnot necessarily appear while doing view source. Using inspect element we can see our input appear within img src
attribute <img src="/resources/images/tracker.gif?searchTerms=alex">
so here we can simply breakout of the string and do "><img src=x onerror=alert()
DOM xss in document.write
sink via location.search
source inside select
element
document.write
sink via location.search
source inside select
elementHere, the store name is taken from url search parameter storeId and inside select statement the name of stores London, Paris, Milan and one from the search parameters are looped through and appended using document.write and select tag is closed.
If we insert https://vulnerable-site.com/product?productId=1&storeId=meow we will see following in inspect element DOM
We can just close the tag and do </select><img src=1 onerror=alert()>
DOM xss in innerHTML using source location.search
Here, we can simply use https://vulnerable-site.com/?search=<img src=x onerror=alert()>
DOM xss in jquery anchor href attribute
Here this is the url https://website.com/feedback?returnPath=/ when clicking the back button the href attribute of anchor tag is set from url search query returnPath
whose value is /
.
We can simply put returnPath=javascript:alert()
in the url so when back button is clicked javascript is fired.
DOM xss in Angular JS
When a site uses angular js we can see in html source or DOM, an attribute like ng-app
. We can use angular js to execute javascript without angle brackets or double quotes. {{$on.constructor('alert(1)')()}}
Reflected DOM xss
There is search functionality on the page when we search for anything like meow. The displaying of search results is done via javascript in /resource/js/searchResults.js Here search() function is called with search-results as argument.
searchResults.js file.
Here, since this search function is called with search-results
as argument. A get request is performed to /search-results?search=meow
endpoint. If a blog containing string meow
exists a json object will be returned {"results":[],"searchTerm":"meow"}
this object is set as searchResultObj
variable using eval()
. Here "
is escaped using \
so we can simply search for meow\"-alert(1)}//
to execute javascript. The value inside eval() funtion will become this.
And finally this will be written to the dom
Stored DOM xss
Here, for loading all the users comments below javascript is used. In the source loadComments('/post/comment')
funtion is called with /post/comment endpoint. This loadComments function is making GET request to /post/comment?postId=10
endpoint and using JSON.parse on the received response and setting it as comments
variable. displayComments function is used passing the received comments object as argument. Another thing to note here is escapeHTML function is created which takes html as argument and replaces occurence of <
with <
and >
with >
. but it only checks the occurence of < and > once here it had to loop through the passed html and replace every occurence of < and >.
NOw, in displayComments() function the received comments object is looped through and for every comment its author, website, etc is taken. Using javascript itself a paragraph tag is created inside which img tags is created and the comment avatar image is set, anchor tag is created with id as author name href as author website and so on. Now, this paragraph tag firstPElement
innerhtml is taken and comment author's name is added by using escapeHTML() function.
Here, simply when submitting the comment we can enter author name as <><img src=x onerror=alert()>
to execute javascript because the escapeHTML() function is only replacing first occurence of < and >.
Content Security Policy
Content Security Policy or CSP is a browser security policy which works by restricting scripts or images that a page can load also whether a page can be framed by other pages. We can determine if the page is using CSP through HTTP response header Content-Security-Policy
with value containing the policy. Some policies are:
Below allows scripts to be loaded only from the same origin as the page itself.
Below a site administrator wants to allow content from a trusted domain and all its subdomains.
Below allows content from only the same origin, images to be loaded from any origin, media like audio and video to be loaded only from example.org and example.net and scripts to be loaded only from userscripts.example.com
Last updated