DEV Community

Cover image for A Comprehensive Guide to XSS Attacks and Defenses
wetest
wetest

Posted on

A Comprehensive Guide to XSS Attacks and Defenses

Part 1: Basics of Vulnerability Attacks and Defenses

XSS belongs to the field of vulnerability attacks and defenses. To study it, we need to understand some jargon in this field for better communication and exchange. At the same time, I have established a simple attack model for XSS vulnerability learning.

1. Vulnerability Terminology

VUL

Vulnerability (VUL) refers to bugs that can cause damage to a system or can be used to attack a system.

POC

Proof of Concept (POC) is the evidence of a vulnerability; it can be a textual description and screenshot proving the existence of a vulnerability, but more often, it is the code that proves the vulnerability's existence. Generally, it does not damage the vulnerable system.

EXP

Exploit (EXP) is the code used to attack a system using a vulnerability.

Payload

Payload is the attack code that you include in an exploit.

PWN

PWN is a slang term in hacker language, referring to breaking a device or system.

Zero-day Exploit and Zero-day Attack

Zero-day exploit usually refers to a security vulnerability that has no patch available.

Zero-day attack refers to an attack exploiting such a vulnerability.

Zero-day exploit is not only the favorite of hackers, but the number of zero-day exploit mastered is also an important parameter to evaluate a hacker's technical level.

CVE Vulnerability Number

Common Vulnerabilities and Exposures (CVE) assigns a public name to widely recognized information security vulnerabilities or exposed weaknesses.

You can search for an introduction to the vulnerability on the https://cve.mitre.org/ website based on the CVE number of the vulnerability.

2. Vulnerability Attack Model

Image description

The diagram above shows a simple attack model. An attack is the process of injecting the Payload through the injection point and executing it at the execution point. If the process goes smoothly, it indicates that the vulnerability has been exploited.

Part 2: XSS Fundamentals

1. What's XSS?

XSS stands for Cross-site scripting. Attackers exploit the injection point of a website to insert malicious code (Payload) that can be executed and parsed on the client-side. When the victim visits the website, this malicious code is executed at the client's execution point, achieving the attacker's goals, such as obtaining user permissions, malicious propagation, phishing, and other behaviors.

2. Classification of XSS

It is difficult to learn XSS well without understanding its classification. There are many misunderstandings about the classification of XSS, and many articles explain it incorrectly. Here, I provide a relatively good classification of XSS.

2.1 Classification by Payload Source

Stored XSS is a type of cross-site scripting attack in which the malicious code (Payload) is permanently stored on the server. Therefore, it is also called persistent XSS. When the browser requests data, the data containing the Payload is uploaded from the server and executed on the client-side.

The process is shown in the diagram:

Image description

An example of a stored XSS attack: The attacker includes the malicious code (Payload) in the content of the posted message, which is then stored in the database. When the victim visits the page containing the message, the malicious code (Payload) is executed.

Reflected XSS is a type of cross-site scripting attack, also known as non-persistent XSS. In the first scenario, the Payload originates from the client-side and is executed directly on the client-side. In the second scenario, the temporary data sent from the client to the server is processed and then directly echoed back to the client-side for execution.

The process is shown in the diagram:

Image description

Two examples of reflected XSS attacks:

  1. The attacker spreads a link containing the Payload, and when the victim visits this link, the Payload is executed on the client-side.

  2. The victim enters content containing the Payload into the client-side search box, and the server echoes back a page indicating that the search content was not found, at which point the Payload is executed.

2.2 Classification by Payload Location

DOM-based XSS refers to a type of cross-site scripting attack that occurs when client-side JavaScript code manipulates the DOM (Document Object Model) or BOM (Browser Object Model), causing the Payload (malicious code) to execute. Since the execution of the Payload is primarily due to the manipulation of the DOM, it is called DOM-based XSS. However, manipulating the BOM can also cause the Payload to execute, so this term is somewhat inaccurate, and calling it JavaScript-based XSS would be more appropriate.

The Payload in DOM-based XSS is not in the HTML code, which brings difficulties to automated vulnerability detection.

The process is shown in the diagram:

Image description

Reflected DOM-based XSS example: The victim enters content containing the Payload into the client-side search box, and the server echoes back a page indicating that the search content was not found, at which point the Payload is executed.

Stored DOM-based XSS example: The client retrieves content containing the Payload from the server API, and then JavaScript manipulates the DOM or BOM, causing the Payload to execute.

HTML-based XSS refers to a type of cross-site scripting attack in which the malicious code (Payload) is included in the HTML returned by the server. When the browser parses the HTML, the malicious code is executed. This type of vulnerability is easier to perform automated vulnerability detection because the Payload is located within the HTML code. Of course, HTML-based XSS can also be classified as reflected and stored.

The process is shown in the diagram:

Image description

Reflected HTML-based XSS example: The victim enters content containing the Payload into the client-side search box, and the server echoes back a page indicating that the search content was not found, at which point the Payload is included in the HTML and executed.

Stored HTML-based XSS example: The attacker includes the malicious code (Payload) in the content of the posted message, which is then stored in the database. When the victim visits the page containing the message, the Payload is executed within the HTML page.

3. XSS Attack Objectives and Risks

3.1 Objectives

  1. Cookie hijacking: Attackers can use XSS to steal users' cookies, which may contain sensitive information such as login credentials or session tokens.

  2. Web page tampering, phishing, and malicious propagation: Attackers can use XSS to modify web page content, creating phishing schemes or spreading malicious links and software.

  3. Website redirection: Attackers can use XSS to redirect users to other websites, potentially leading them to malicious sites or phishing pages.

  4. Obtaining user information: Attackers can use XSS to access and collect users' personal information, such as email addresses, phone numbers, or other sensitive data.

3.2 Risks

  1. Propagation-related risks: XSS attacks can lead to the spreading of malware, malicious links, or phishing schemes, which can result in further damage to users or systems.

  2. System security threats: XSS attacks can pose threats to the security of both user devices and web applications, potentially leading to unauthorized access, data breaches, or other security incidents.

Part 3: Payload of XSS Attack

In this section, we will analyze the Payload in the attack model. To understand Payload, we must understand encoding. To learn JavaScript well, we must also understand encoding. To truly excel in cybersecurity, mastering encoding is fundamental.

1. Encoding Basics

Although the encoding part is the most important and may be tedious, it is essential to master. Many transformed Payloads are built on your encoding foundation. Here, we will use a hexadecimal encoding tool to help you thoroughly learn encoding.

1.1 Encoding Tools

Hexadecimal viewer: Convenient for viewing the hexadecimal encoding of files.

MAC: Hex Friend

Windows: HxD

Editor Sublime: You can use Sublime to save files in different encoding types.

Image description

1.2 ASCII

  • Definition:

American Standard Code for Information Interchange (ASCII) is a computer encoding system based on the Latin alphabet, mainly used for displaying modern English and other Western European languages.

  • Encoding method:

ASCII is a single-byte encoding. It defines the encoding of 128 characters, occupying only the last 7 bits of a byte, with the first bit uniformly set to 0. Numbers 0 to 31 and 127 (a total of 33) are control characters or communication-specific characters. Numbers 32 to 126 (a total of 95) are characters (with 32 being a space).

1.3 ISO-8859-1 (Latin1)

  • Definition:

Latin1 is an alias for ISO-8859-1. In addition to the characters included in ASCII, ISO-8859-1 also includes characters corresponding to Western European languages, Greek, Thai, Arabic, and Hebrew. The euro symbol appeared relatively late and was not included in ISO-8859-1.

  • Encoding method:

ISO-8859-1 encoding is a single-byte encoding and is downward compatible with ASCII. Its encoding range is 0x00-0xFF, with 0x00-0x7F being identical to ASCII, 0x80-0x9F being control characters, and 0xA0-0xFF being text symbols.

  • Note:

The character range represented by ISO-8859-1 encoding is very narrow and cannot represent Chinese characters. However, since it is a single-byte encoding and consistent with the most basic unit of computer representation, ISO-8859-1 encoding is still often used for representation. For example, although the two characters "中文" do not exist in ISO-8859-1 encoding, using GB2312 encoding as an example, they should be represented by the two characters "d6d0 cec4". When using ISO-8859-1 encoding, they are split into four bytes: "d6 d0 ce c4" (in fact, when storing, it is also processed in bytes). Therefore, Latin1 in MySQL can represent characters of any encoding.

  • The relationship between Latin1 and ASCII encoding:

Latin1 is fully compatible with ASCII.

1.4 Unicode encoding (UCS-2)

Code Point: Code point, simply understood as the digital representation of characters. A character set can generally be represented by one or more two-dimensional tables composed of multiple rows and multiple columns. The points where rows and columns intersect in a two-dimensional table are called code points, and each code point is assigned a unique number, which is called code point value or code point number.

BOM (Byte Order Mark): Byte order, which appears in the header of the file, indicates the order of bytes. The first byte is in front, which is "Big-Endian", and the second byte is in front. It is "Little-Endian".

There is a character called "ZERO WIDTH NO-BREAK SPACE" in the Unicode character set, and its code point is FEFF. And FFFE is a character that does not exist in Unicode, so it should not appear in actual transmission. Before transmitting the byte stream, we can pass the character "ZERO WIDTH NO-BREAK SPACE" to indicate the big and small end, so the character "ZERO WIDTH NO-BREAK SPACE" is also called BOM.

BOM can also be used to indicate the encoding method of text. Windows uses BOM to mark the encoding method of text files. It doesn't matter whether the file on the Mac has a BOM or not.

For example: \u00FF: 00 is the first byte, FF is the second byte. Like the code point representation, it belongs to the big-endian method.

Unicode coded character set: it aims to collect all characters in the world, and assign a unique character number to each character, that is, a code point (Code Point), which is represented by U+ followed by a hexadecimal number. All characters are divided into 17 planes (numbered 0-16) according to the frequency of use, that is, the basic multilingual plane and the supplementary plane. The basic multilingual plane, also known as plane 0, collects the most widely used characters, code points from U+0000 to U+FFFF, and each plane has 216=65536 code points;

Unicode encoding: The characters in the Unicode character set can have many different encoding methods, such as UTF-8, UTF-16, UTF-32, compression conversion, etc. What we usually call Unicode encoding is UCS-2, which directly maps character numbers (same as code points in Unicode) to character encodings, that is, character numbers are character encodings, and there is no special encoding algorithm conversion in the middle. It is a fixed-length double-byte encoding: because our UCS-2 only includes this multilingual plane (U+0000 to U+FFFF).

BOM of UCS-2: big endian mode: FEFF. Little endian mode: FFFE.

The file is saved as UTF-16 BE with BOM, which is equivalent to the big endian mode of UCS-2. You can see that the hexadecimal system starts with FEFF

Image description

The relationship between Latin1 and Unicode encoding: Latin1 corresponds to the first 256 code points of Unicode.

1.5 UTF-16

  • Definition and encoding: UTF-16 is one of the usage methods of Unicode. Characters defined in the Unicode Basic Multilingual Plane (whether they are Latin letters, Chinese characters or other characters or symbols) are stored in 2 bytes. Characters defined in the auxiliary plane are stored as two 2-byte values in the form of a surrogate pair. is a double-byte encoding.

  • The relationship between UTF-16 and UCS-2: UTF-16 can be regarded as the superset of UCS-2. Before there are no auxiliary plane characters (surrogate code points), UTF-16 and UCS-2 refer to the same meaning. But when the auxiliary plane characters are introduced, it is called UTF-16. Now if some software claims to support UCS-2 encoding, it actually implies that it cannot support character sets exceeding 2bytes in UTF-16. For UCS codes less than 0x10000, UTF-16 encoding is equal to UCS codes.

  • BOM of UTF-16: big-endian mode: FEFF. Little endian mode: FFFE.

1.6 UTF-8

  • Definition and encoding: UTF-8 is the most widely used implementation of Unicode on the Internet. This is an encoding designed for transmission, and makes encoding borderless, so that characters from all cultures in the world can be displayed. One of the biggest features of UTF-8 is that it is a variable-length encoding method. It can use 1~4 bytes to represent a symbol, and the byte length varies according to different symbols. When the character is in the range of ASCII code, it is represented by one byte, and the encoding of one byte of ASCII character is reserved as it. Note that a Chinese character in unicode occupies 2 bytes, while a Chinese character in UTF-8 occupies 3 bytes). From unicode to utf-8 is not a direct correspondence, but needs some algorithms and rules to convert.

Image description

  • BOM for UTF8: EFBBBF. There is no character sequence problem in UTF-8, but BOM can be used to indicate that this file is a UTF-8 file.

The file is saved as UTF-8 BE with BOM, you can see that the hexadecimal starts with EFBBBF

Image description

1.7 GBK/GB2312

Definition and encoding: GB2312 is the earliest version of Chinese character encoding that only contains 6763 Chinese characters. GB2312 only supports simplified characters and is incomplete, which is obviously not enough. GBK encoding is an extension of GB2312 encoding, fully compatible with GB2312 standard, supporting simplified and traditional characters, including all Chinese characters. GBK encoding adopts a single-double-byte encoding scheme. The single-byte is consistent with Latin1, and the double-byte is the Chinese character part. The encoding range: 8140-FEFE, excluding the xx7F code point, a total of 23940 code points.

The relationship between GBK and Latin1: The GBK single-byte coding area is consistent with the Latin1 coding.

The relationship between GBK and Unicode: GBK and Unicode character set encoding are different but compatible. For example, although the Unicode value of "Han" is different from GBK, assuming that Unicode is a040 and GBK is b030, they can be converted accordingly. The Unicode area of Chinese characters: 4E00-u9FA5.

GBK and UTF-8: GBK Chinese characters adopt double-byte encoding which is smaller than the three-byte encoding in UTF-8. But UTF-8 is more general. GBK and UTF-8 conversion: GBK —> Unicode —> UTF8

2. Coding in the front end

Once you have the coding foundation, you can get to know the coding in the front end, so that you can really understand the Payload. What I have here should be the most comprehensive summary.

2.1 Base64

Base64 can be used to encode binary byte sequence data into text composed of ASCII character sequences. When using, specify Base64 in the transfer encoding method. The characters used include 26 uppercase and lowercase Latin letters, 10 numbers, plus sign + and slash /, a total of 64 characters and the equal sign = are used as suffixes. So a total of 65 characters.

Put 3 bytes of data into a 24-bit buffer successively, and the byte that comes first occupies the high position. If the data is less than 3 bytes, the remaining bits in the buffer are filled with 0. Take out 6 bits each time and use Base64 characters as the encoded output of the original data. For encoding, if the length of the original data is not a multiple of 3 and there is 1 input data left, add 2 = after the encoding result; if there are 2 input data left, add 1 = after the encoding result. It can be seen that the Base64 encoded data is about 3/4 of the original data.

The standard Base64 is not suitable for direct transmission in the URL, because the URL encoder will change the / and + characters in the standard Base64 into a form like %XX, and these % symbols need to be converted when they are stored in the database , because the % sign is already used as a wildcard in ANSI SQL. To solve this problem, an improved Base64 encoding for URLs can be used, which does not pad the = sign at the end, and changes the + and / in the standard Base64 to - and _ respectively, thus eliminating the need for URL encoding and decoding The conversion required for storage with the database avoids the increase in the length of the encoded information in the process, and unifies the format of object identifiers in databases, forms, etc.

window.btoa/window.atob base64 encoding (binary to ascii) and decoding only supports Latin1 character set.

2.2 JS escape characters

The js character string contains some special escape characters starting with a backslash, which are used to represent non-printing characters, and characters for other purposes can also be escaped to represent unicode and Latin1 characters.

Note:

  1. The newline character \n used in innerHTML will only display a space and will not break the line.

  2. Any unicode character and Latin1 character can be represented by \n, \u and \x. Through this, you can encrypt js to ensure js security and carry out covert attacks.

Example:

Image description

2.3 URL encoding

RFC 1738 stipulates that "only letters and numbers [0-9a-zA-Z], some special symbols "$-_.+!*'()," [not including double quotation marks], and certain reserved words, can Can be used directly in a URL without encoding". Therefore, when the link contains Chinese or other non-compliant characters, it needs to be encoded. However, due to the large number of browser manufacturers, there are many ways to encode URLs. If the encoding is not processed uniformly, it will have a great impact on code development and garbled characters will appear.

  • URL encoding rules: Convert the characters to be encoded to UTF-8 encoding, and then add % in front of each byte.

  • JS provides us with three URL encoding methods for strings: escape, encodeURI, encodeURIComponent

  • escape: Since escape has been suggested to give up, please don’t use it

  • encodeURI: 82 characters that encodeURI does not encode: !#$&'()*+,/:;=?@-._~0-9a-zA-Z, it can be seen that the reserved characters in the url will not be modified Encoding, so it is suitable for url overall encoding

  • encodeURIComponent: This is the most useful encoding function for us. There are 71 characters that encodeURIComponent does not encode: !, ', (,), *, -, ., _, ~, 0-9, az, AZ.

It can be seen that the reserved words in the url are encoded, so when the passed parameters

Including the reserved words (@, &, =) in these urls, they can be encoded and transmitted by this method

The decoding methods corresponding to these three methods: unescape, decodeURI, decodeURIComponent

2.4 HTML character entities

Reserved characters in HTML must be replaced with character entities. Only in this way can it be displayed as characters, otherwise it will be parsed as HTML.

Character entity encoding rules: escape character = &#+ascii code; = & entity name;

Conversion method:

Image description

2.5 Page Encoding

Page encoding settings:

Script encoding settings:

Note: If you want JS to be used normally in UTF-8 and GBK, you can escape characters in all strings containing Chinese in JS.

3. Payload classification

Now you can know the Payload, and I have to say that the classification of Payload here can help you know Payload very well. It also helps you better correspond to the execution point.

3.1 Atomic Payload

The lowest level Payload.

javascript code snippet

It can be directly executed in eval, setTimeout, setInterval, and can also form high-level Payload through HTML, etc.

javascript: javascript pseudo-protocol

Structure: javascript:+js code. It can be executed when the href attribute of the a tag is clicked and window.location.href is assigned.

DATA URI protocol

DATA URI structure: data:[][;base64], . The DATA URI data will become the executable Payload contained in the src attribute and object data attribute of the iframe.

String escape variant javascript code snippet

unicode or Latin-1 for character strings.

Image description

3.2 Pure HTML Payload

This Payload feature does not have executable JS, but there is a risk of spreading, and other sites can be injected into the attacked website.

HTML fragment containing link jumps

mainly spreading hazards

Image description

3.3 HTML Fragment Payload Containing Atomic Payload

Script tag fragment

The payload of the script tag fragment can introduce external JS or directly executable script. This kind of Payload generally cannot be executed by directly copying it to innerHTML, but it can be executed on IE. However, it can be executed through document.write.

Example:

Image description

HTML fragment containing event handling

For example: HTML fragments containing img's onerror, svg's onload, input's onfocus, etc. can all be turned into executable Payloads.

Image description

HTML fragments containing executable JS attributes

1. javascript pseudo-protocol

Image description

2. DATA URI

Example:

Image description

Here we only introduce the main Payload, and there are many uncommon Payloads.

Part 4: XSS Attack Model Analysis

In this part, we analyze the execution point and injection point of XSS according to the vulnerability attack model. Analyzing these two points is actually the process of finding loopholes.

1. XSS vulnerability execution point

  1. The page goes straight out of the Dom
  2. Client jump link: location.href / location.replace() / location.assign()
  3. Write the value to the page: innerHTML, document.write and various variants. Here, the HTML fragment carrying the executable Payload is mainly written.
  4. Script dynamic execution: eval, setTimeout(), setInterval()
  5. Unsafe attribute setting: setAttribute. Unsafe attributes have been seen before: href of a tag, src of iframe, data of object
  6. HTML5 postMessage data from insecure domain.
  7. Defective third-party libraries.

2. XSS vulnerability injection point
See where we can inject our payload

  1. The server returns data
  2. Data entered by the user
  3. Link parameters: window.location object three attributes href, search, search
  4. Client storage: cookie, localStorage, sessionStorage
  5. Cross-domain calls: postMessage data, Referer, window.name

The above content basically includes all execution points and injection points. It is very helpful for everyone to attack and defend XSS vulnerabilities.

Part 5: XSS Attack Defense Strategy

1. Tencent's internal public security defense and emergency response

  1. Access public DOM XSS defense JS
  2. Internal vulnerability scanning system scan
  3. Tencent Security Emergency Response Center: Security workers can submit Tencent-related vulnerabilities through this platform and get rewards based on vulnerability ratings.
  4. Emergency response system for major failures.

2. Secure coding
2.1 Enforce point defense method

Image description

2.2 Other security defense methods

  • 1. Use httpOnly for cookies
  • 2. Use Content Security Policy in HTTP Header

3. Code review
Summarize the XSS checklist for code self-test and inspection

4. Tools to automatically detect XSS vulnerabilities
It is time-consuming to manually detect XSS vulnerabilities. Can we write a set of automatic XSS detection tools? I actually know that the injection point, execution point, and Payload automation process are completely possible.

The difficulty of automatic XSS detection lies in the detection of DOM type XSS. Because the complexity of the front-end JS is high, including static code analysis and dynamic execution analysis are not easy.

About WeTest Security Testing

Effective security testing is a critical component of maintaining web security for digital businesses. With WeTest Security Testing, organizations can identify vulnerabilities, address security issues, and enhance the overall security posture of their applications and data. Regular security testing, including application security testing, is vital to protect against emerging threats and safeguard confidential information.

To help you better understand our product, we offer a trial opportunity. You can try our Application Security Scan Testing product for free and experience its features and advantages. We believe that once you personally experience our product, you will be satisfied with its powerful security performance and user-friendliness. Get started your testing with WeTest security Testing today!

Image description

For more information, contact WeTest team at → WeTest-All Test in WeTest

Top comments (0)