What is Cross-Site Scripting


Image for post
Image for post


The implications of successful Cross-Site Scripting attacks are:

  • Account hijacking — An attacker can hijack the user’s session before the session cookie expires and take actions with the privileges of the user who accessed the URL, such as issuing database queries and viewing the results.
  • Malicious script execution — Users can unknowingly execute JavaScript, VBScript, ActiveX, HTML, or even Flash content that has been inserted into a dynamically generated page by an attacker.
  • Worm propagation — With Ajax applications, XSS can propagate somewhat like a virus. The XSS payload can autonomously inject itself into pages, and easily re-inject the same host with more XSS, all of which can be done with no hard refresh. Thus, XSS can send multiple requests using complex HTTP methods to propagate itself invisibly to the user.
  • Information theft — Via redirection and fake sites, attackers can connect users to a malicious server of the attacker’s choice and capture any information entered by the user.
  • Denial of Service — Often by utilizing malformed display requests on sites that contain a Cross-Site Scripting vulnerability, attackers can cause a denial of service condition to occur by causing the host site to query itself repeatedly .
  • Browser Redirection — On certain types of sites that use frames, a user can be made to think that he is in fact on the original site when he has been redirected to a malicious one, since the URL in the browser’s address bar will remains the same. This is because the entire page isn’t being redirected, just the frame in which the JavaScript is being executed is redirected.
  • Manipulation of user settings — Attackers can change user settings for nefarious purposes.
  • Bypass Content-Security-Policy protection — Attackers can inject a malformed tag formation, known as dangling tag injection, which in some cases allows injected script to reuse valid nonce on the page and bypass script source restriction. Additionally dangling tag injection can be used to steal sensitive information embedded in HTML response if browser is able to make a request to the injected link.
  • Base tag injection: Attacker can cause relative links on a page to load from a different domain by modifying the base URL for the page via base tag injection.
  • Link prefetch injection: While unable to execute script, attackers can use link tag with rel=prefetch that will make browsers pre-fetch the specified link even though it is never rendered and rejected subsequently due to web application enforced cross-site policy (e.g. CSP protections).
  • Edge side includes (ESI) Injection — ESI is a markup language used in various HTTP devices, such as reverse proxies and load balancers, that are positioned between client and server. An attacker can inject ESI markup to perform critical attacks such as cross-site scripting and HTTPOnly cookie protection bypass.


Cross-Site Scripting attacks can be avoided by carefully validating all input, and properly encoding all output. When validating user input, verify that it matches the strictest definition of valid input possible. For example, if a certain parameter is supposed to be a number, attempt to convert it to a numeric data type in your programming language.

PHP: intval(“0”.$_GET[‘q’]);

ASP.NET: int.TryParse(Request.QueryString[“q”], out val);

The same applies to date and time values, or anything that can be converted to a stricter type before being used. When accepting other types of text input, make sure the value matches either a list of acceptable values (white-listing), or a strict regular expression. If at any point the value appears invalid, do not accept it. Also, do not attempt to return the value to the user in an error message.

Most server side scripting languages provide built in methods to convert the value of the input variable into correct, non-interpretable HTML. These should be used to sanitize all input before it is displayed to the client.

PHP: string htmlspecialchars (string string [, int quote_style])

ASP.NET: Server.HTMLEncode (strHTML String)

When reflecting values into JavaScript or another format, make sure to use a type of encoding that is appropriate. Encoding data for HTML is not sufficient when it is reflected inside of a script or style sheet. For example, when reflecting data in a JavaScript string, make sure to encode all non-alphanumeric characters using hex (\xHH) encoding.

If you have JavaScript on your page that accesses unsafe information (like location.href) and writes it to the page (either with document.write, or by modifying a DOM element), make sure you encode data for HTML before writing it to the page. JavaScript does not have a built-in function to do this, but many frameworks do. If you are lacking an available function, something like the following will handle most cases:

s = s.replace(/&/g,’&amp;’).replace(/”/i,’&quot;’).replace(/</i,’&lt;’).replace(/>/i,’&gt;’).replace(/’/i,’&apos;’)

Ensure that you are always using the right approach at the right time. Validating user input should be done as soon as it is received. Encoding data for display should be done immediately before displaying it.

For Security Operations:

Server-side encoding, where all dynamic content is first sent through an encoding function where Scripting tags will be replaced with codes in the selected character set, can help to prevent Cross-Site Scripting attacks.

Many web application platforms and frameworks have some built-in support for preventing Cross-Site Scripting. Make sure that any built-in protection is enabled for your platform. In some cases, a misconfiguration could allow Cross-Site Scripting. In ASP.NET, if a page’s EnableViewStateMac property is set to False, the ASP.NET view state can be used as a vector for Cross-Site Scripting.

An IDS or IPS can also be used to detect or filter out XSS attacks. Below are a few regular expressions that will help detect Cross-Site Scripting.

Regex for a simple XSS attack:

The above regular expression would be added into a new Snort rule as follows:

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:”NII Cross-Site Scripting attempt”; flow:to_server,established; pcre:”/((\%3C)|<)((\%2F)|\/)*[a-z0–9\%]+((\%3E)|>)/i”; classtype:Web-application-attack; sid:9000; rev:5;)

Paranoid regex for XSS attacks:

This signature simply looks for the opening HTML tag, and its hex equivalent, followed by one or more characters other than the new line, and then followed by the closing tag or its hex equivalent. This may end up giving a few false positives depending upon how your web application and web server are structured, but it is guaranteed to catch anything that even remotely resembles a Cross-Site Scripting attack.

For QA:

Fixes for Cross-Site Scripting defects will ultimately require code based fixes. Read the the following links for more information about manually testing your application for Cross-Site Scripting.


GET /rootlogin.asp?txtPassPhrase=12345&txtName=12345%3csCrIpT%3ealert(23787)%3c%2fsCrIpT%3e&txtHidden=This%20was%20hidden%20from%20the%20user HTTP/1.1
Referer: http://zero.webappsecurity.com:80/rootlogin.asp
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Accept: */*
Pragma: no-cache
Host: zero.webappsecurity.com
X-Scan-Memo: Category=”Audit”; Function=”createStateRequestFromAttackDefinition”; SID=”4CB6A5B5DCE0472B33E84FCFCB1B0844"; PSID=”FDA700FD7D44E7C11B44F001954F7BDF”; SessionType=”AuditAttack”; CrawlType=”None”; AttackType=”QueryParamManipulation”; OriginatingEngineID=”1354e211–9d7d-4cc1–80e6–4de3fd128002"; AttackSequence=”2"; AttackParamDesc=”txtName”; AttackParamIndex=”1"; AttackParamSubIndex=”0"; CheckId=”(null)”; Engine=”Cross+Site+Scripting”; Retry=”False”; SmartMode=”NonServerSpecificOnly”; AttackString=”12345%253csCrIpT%253ealert(23787)%253c%252fsCrIpT%253e”;
Connection: Keep-Alive
Cookie: CustomCookie=WebInspect69383ZXB3FCEA2CCD6849B0A63D3EFF65615601Y3637;status=yes;username=;userid=;sessionid=;ASPSESSIONIDCARBTACT=ECEJMBECHGCGCFFMPMFHDPPE;state=;passes3=;passes=;passes2=

Response :

HTTP/1.1 200 OK
Date: Fri, 13 May 2011 19:48:23 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 110
Content-Type: text/html
Cache-control: private


Invalid Data 12345<sCrIpT>alert(23787)</sCrIpT><br>Please try again.


Best book for Hacking and Penetration Testing

Penetration Testing: A Hands-On Introduction to Hacking — https://amzn.to/2YUvteh

The Hacker Playbook 3: Practical Guide To Penetration Testing — https://amzn.to/2KEDonb

Mastering Modern Web Penetration Testing — https://amzn.to/2Hct6IX

Kali Linux Web Penetration Testing Cookbook: Identify, exploit, and prevent web application vulnerabilities with Kali Linux 2018.x, 2nd Edition — https://amzn.to/31IjPQG


Blogger | Security Researcher | Digital forensic analyst | Twitter — @mrunal110

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store