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-html
Rendering 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.