What is an XSS attack

In a cross-site scripting (XSS) attack, an attacker can execute a malicious script in the victim’s browser. This attack is usually done by inserting malicious code (JavaScript) into a web page. Attackers are generally able to:

  • Modifying web content
  • Redirect users to other sites
  • Access a user’s Cookie and use this information to impersonate the user
  • Access key information about the user’s system, such as geolocation, webcam, and file system
  • Inject Trojan functionality into the application

If the user being attacked has higher privileges in the application. An attacker can take full control of an application and destroy all users and their data.

XSS attack type

There are three common XSS attacks: storage XSS attack, reflection XSS attack and DOM-based XSS attack.

  • The storage type mainly stores THE XSS code on the server (database, file system, etc.) and reparses the XSS code when the user requests the resource again later, resulting in attacks.
  • Reflective attacks occur when an application uses dynamic pages to display error messages to the user. An XSS reflective attack can occur if malicious code is injected into the message.
  • Dom-based mainly uses scripts to directly modify the DOM structure of the client, which is generally a vulnerability of front-end JavaScript.

How do I block XSS injection

Here is a simple POST method that simulates creating a Book and saving it to the database.

@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    IBookService bookService;

    @PostMapping
    public void saveBook(@RequestBody Book book) { bookService.save(book); }}Copy the code

We can simulate a stored XSS attack by doing a JS injection of the type value at the time of saving.

This vulnerability can be exploited by others to inject malicious code:

X – XSS – Protection response headers

Some browsers have built-in support for filtering reflex XSS attacks. Helps XSS protection to a certain extent. We need to add the following in the HTTP response header to ensure that this feature is enabled and instruct the browser to block XSS attacks if they are detected.

X-XSS-Protection: 1; mode=block
Copy the code

If your project introduces Spring Security, this header is automatically added by default.

Add the Content-security-Policy response header

Compliant Content Security Policy (CSP) browsers will only execute scripts loaded from source files received from our “allowed” listed domains and ignore all other scripts, such as inline scripts. We can add the ability to enable content security policies in the browser by subheading.

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf().disable()// To simplify the example and make XSS injection more clear, CSRF protection is disabled here. Do not use it in real situations.
                .authorizeRequests().anyRequest().authenticated()
                .and().httpBasic()
                .and()
                .headers().contentSecurityPolicy("script-src 'self'"); }}Copy the code

Here are all the browsers that support CSP:

Into the parameter validation

We know that the field only needs Chinese, English and numeric characters, so we can use Spring’s Validator to add the @Pattern annotation to the field.

    @NotNull
    @pattern (message=" Type can only support Chinese and English numbers ", regexp =" [u4E00-\ u9FA5_A-za-z0-9]+")
    private String type;
Copy the code

Then add @valid to the method that receives Book so that it is automatically validated when a request occurs:

@PostMapping
public void saveBook(@RequestBody @Valid Book book) {
    bookService.save(book);
}
Copy the code

The client

Mainstream front-end frameworks like Angular, React, and Vue can also avoid the problems of traditional development:

  • To systematically prevent XSS errors, Angular treats all values as untrusted by default. Angular cleans up and escapes untrusted values when inserting values from templates into the DOM through attributes, attributes, styles, class bindings, or interpolation.
  • JSX(React) allows you to pass a function as an event handler, rather than a string that might contain malicious code.
  • String variables in the React view are automatically escaped.
  • Vue’s official documentation also says,v-htmlRendering arbitrary HTML dynamically is dangerous and can easily trigger XSS injection, so V-HTML should never be used on user-submitted information.

conclusion

Preventing XSS vulnerability mainly involves a combination of the following measures:

  • Use the X-XSS-protection response header to take advantage of browser support to limit reflected XSS attacks.
  • Use the Content-security-Policy response header to enable the browser’s CSP functionality.
  • Verify input information using Validator.
  • React uses the JSX transfer function as an event handler, and Vue uses V-HTML only for trusted content. For user input, v-HTML must be prohibited.