In a XSS attack, the attacker’s goal is to inject a malicious script into the user’s browser and have the browser execute the script. The vulnerability of web applications to XSS attacks is because of not validating user’s input and/or not encoding/sanitizing data when rendering into a browser. Don’t confuse Cross Site Scripting with Cross Site Request Forgery (CSRF).
A successful XSS attack could be devastating. Examples of damages include exposing the victim’s sensitive data, displaying inappropriate/unintended content, involuntarily transferring of money, impersonating the user’s account etc …
XSS attack is listed under the top ten most critical application security risks for 2017.
Several XSS types of attack describe how a malicious script arrives at a user’s browser: stored XSS attacks, reflected XSS attacks, and server vs client XSS attacks.
In a stored XSS attack, the attacker manages to store the malicious script on a permanent storage such as in the targeted application’s database, file system,
Examples of stored XSS attack scenarios:
In a reflected XSS attack, the malicious script originates from a request, comes to the server and then reflects back to the browser. This attack exploits web applications that uses input fields as part of the response without proper validation. A reflected XSS attack relies on social engineering to lure the victim into involuntarily executing a request that contains a malicious script.
In the example below, which I take directly from WebGoat, the HTML form gathers credit card information from the user and sends to the backend for processing. The backend returns a response message which contains the credit card number for the browser to display. The credit card field accepts any string and the backend does not validate it.
Clicking the Purchase button sends the request below to the server.
http://localhost:8080/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=%3Cscript%3Ealert(%27my%20javascript%20here%27)%3C/script%3E4128+3214+0002+1999&field2=111
Here is the code from the server. As you can see, it does not validate field1.
@RequestMapping(method = RequestMethod.GET) public @ResponseBody AttackResult completed(@RequestParam Integer QTY1, @RequestParam Integer QTY2, @RequestParam Integer QTY3, @RequestParam Integer QTY4, @RequestParam String field1, @RequestParam Integer field2, HttpServletRequest request) throws IOException { double totalSale = QTY1.intValue() * 69.99 + QTY2.intValue() * 27.99 + QTY3.intValue() * 1599.99 + QTY4.intValue() * 299.99; userSessionData.setValue("xss-reflected1-complete",(Object)"false"); StringBuffer cart = new StringBuffer(); cart.append("Thank you for shopping at WebGoat. <br />You're support is appreciated<hr />"); cart.append("<p>We have charged credit card:" + field1 + "<br />"); cart.append( " ------------------- <br />"); cart.append( " $" + totalSale);
When the browser displays the response message, it also executes the injected script.
DOM-Based XSS is a subset of client XSS. The DOM here refers to the Document Object Model. A DOM-Based XSS attack is an attack on the client. In a DOM based attack, the client processes the request instead of sending it to the server. We call the locations where the request originates the sources, and the locations where the malicious script executes the sinks.
Below lists the popular sources and sinks which I took directly from this article.
Popular Sources
- document.URL
- document.documentURI
- location.href
- location.search
- location.*
- window.name
- document.referrer
Popular Sinks
- HTML Modification sinks
- document.write
- (element).innerHTML
- HTML modification to behaviour change
- (element).src (in certain elements)
- Execution Related sinks
- eval
- setTimout / setInterval
- execScript
In the example below, the javascript uses the innerHTML to display a greeting message based on the user’s name, without validating the input from the user.
<html> <body> <div id="pageContent"> Welcome, please enter your name: <input id="source" type="text" style="width:400px;font-size:12pt;"> </div> <script> var input = document.getElementById("source") input.addEventListener("keyup", function(event) { event.preventDefault(); // 13 = Enter key if (event.keyCode === 13) { greet(input.value); } }); function greet(name) { document.getElementById("pageContent").innerHTML = "Hello, " + name; } </script> </body> </html>
A malicious user can inject his script via the input text.
The OWASP has an article on preventing XSS attacks. Below is a recap of some of the rules mentioned in the article. You should check it out if you want more guidances on how to escape the inputs at the client.
OWASP article on Cross Site Scripting (XSS)
OWASP article on preventing XSS attacks.
OWASP list of top 10 most critical web application security risks.
OWASP Cross Site Scripting Prevention Cheat Sheet
OWASP DOM Based XSS Prevention Cheat Sheet
Netsparker article “DOM Based Cross-site Scripting Vulnerability”
Using MSAL angular to authenticate a user against azure ADB2C via authorization code flow with Proof Key for Code Exchange.
Azure AD authentication in angular using MSAL angular v2 library
Authenticate against azure ad using certificate in a client credentials flow
Migrating from Microsoft.AspNetCore.Authentication.AzureAD to Microsoft Identity Web authentication library to integrate with Azure AD.
Getting started with Azure AD Self-Service Sign-Up via user flows
Integrate Azure AD B2C reset password user flow in angular using oidc-client-js.
Integrate Azure AD B2C profile editing user flow in angular using oidc-client-js.
Using OAuth2 Client Credentials grant type in Azure ADB2C