In Spring Boot, we can use annotations to defend XSS. Annotations are a lightweight defense that can verify inputs at the method or field level, thus preventing XSS attacks.
Introduce related dependencies
maven dependencies:
<!--JSR-303/JSR-380Annotations for verification --> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>2.6.7</version> </dependency>
If you are using grade, introduce dependencies:
implementation ':spring-boot-starter-validation:2.6.7'
Define @XSS annotation for parameter verification
We can customize a @XSS annotation to mark those parameters that need to be checked. Here is a simple @XSS annotation definition:
package ; import ; import ; import ; import ; import ; import ; @Target(value = {, , , }) @Retention() @Constraint(validatedBy = ) public @interface Xss { String message() default "Illegal input, potential XSS detected"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
Implement custom annotation processor
Next, we need to implement the XSSValidator class, which will be responsible for checking whether the input contains a potential XSS attack script:
package ; import ; import ; import ; import ; import ; /** * xss annotation verification */ public class XssValidator implements ConstraintValidator<Xss, String> { /** * Use the relaxed whitelist that comes with jsoup */ private static final Whitelist WHITE_LIST = (); /** * Define the output settings and turn off prettyPrint (prettyPrint=false), the purpose is to avoid formatting the code during the cleaning process. * This keeps the consistency of input and output content. */ private static final OUTPUT_SETTINGS = new ().prettyPrint(false); /** * Verify that the input value is valid, that is, whether it contains a potential XSS attack script. * * @param value Enter value, XSS attack script cleaning is required. * @param context object that provides information about the verification environment, such as customization of error messages when verification fails. * @return If the cleaned value is the same as the original value, it returns true, which means the input value is valid; otherwise, it returns false, which means the input value is invalid. */ @Override public boolean isValid(String value, ConstraintValidatorContext context) { // Here we first parse the value and encode the single < and > characters in it String oldBody = (value).body().html(); // Use the Jsoup library to clean up the input values to remove potential XSS attack scripts. // Use predefined whitelisting and output settings to ensure that only secure HTML elements and attributes are retained. String newBody = (value, "", WHITE_LIST, OUTPUT_SETTINGS); // Compare whether the cleaned value is the same as the parsed value. The difference indicates that the xss script is filtered // The value and newBody are not used here, because jsoup will encode a single < and > character in the value. If there is a single < in the value, the value and newBody will be different. return (newBody); } }
Use @Xs annotation to defend post requests
If it is a post request, you need to prefix the method parameters with @Valid or @Validated annotation, and then add @Xss annotation on the properties of the entity class.
package ; import ; import ; import ; import ; import ; /** * Xss local defense post request */ @RestController @RequestMapping("/xss/local") public class XssLocalPostController { /** * Use annotations to intercept xss in POST requests, and add @Xss or @Validated annotations to the attributes that need to be intercepted by the entity class. * * @param userLocalLoginPojo Entity Class * @return Entity Class */ @PostMapping("/test") public UserLocalLoginPojo test(@Valid @RequestBody UserLocalLoginPojo userLocalLoginPojo) { return userLocalLoginPojo; } }
Add @Xss annotation to the properties to which XSS defense is to be done:
package ; import ; @Data public class UserLocalLoginPojo { @Xss private String userAccount; }
Test url: http://localhost:8888/xss/local/test
Test post request:
{ "userAccount": "<iframe οnlοad='alert(0)'>demoData</iframe>" }
Test results:
{
"message": "userAccount: Illegal input, potential XSS was detected",
"code": 400,
"result": null
}
Use @Xs annotation to defend get request
If it is a get request, you need to prefix the method parameters with @Xs annotation, and then add @Validated annotation to the class.
package ; import ; import .*; /** * Xss local defense get request */ @RestController @RequestMapping("/xss/local") @Validated public class XssLocalGetController { /** * Use annotations to intercept xss in the get request, add @Xss before the method parameters, and note that the @Validated annotation should be added to the class. * * @param userAccount Request parameters * @return Request Parameters */ @GetMapping("/test") public String test(@Xss String userAccount) { return userAccount; } }
Test url:http://localhost:8888/xss/local/test?userAccount=<iframe>demoData</iframe>
Test results:
{
"message": ": Illegal input, potential XSS detected",
"code": 400,
"result": null
}
This is the article about SpringBoot using annotations for XSS defense. For more related SpringBoot XSS defense content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!