How to validate and sanitize HTTP Get with Spring Boot?

john picture john · Jan 1, 2019 · Viewed 18.9k times · Source

I keep getting this annoying error from Checkmarx code scanner,

Method getTotalValue at line 220 of src\java\com\example\PeopleController.java 
gets user input for the personName element. This element’s value then flows through
the code without being properly sanitized or validated and is eventually 
displayed to the user. This may enable a Cross-Site-Scripting attack. 

Here is my code. I think I did ALL the validation necessary. What else???

@Slf4j
@Configuration
@RestController
@Validated 

public class PeopleController {

    @Autowired
    private PeopleRepository peopleRepository; 

    @RequestMapping(value = "/api/getTotalValue/{personName}", method = RequestMethod.GET)
    @ResponseBody
    public Integer getTotalValue(@Size(max = 20, min = 1, message = "person is not found") 
    @PathVariable(value="personName", required=true) String personName) {

        PersonObject po = peopleRepository.findByPersonName(
                            Jsoup.clean(personName, Whitelist.basic()));

        try {
            return po.getTotalValue(); 
            } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }  


@ExceptionHandler
    public String constraintViolationHandler(ConstraintViolationException ex) {
        return ex.getConstraintViolations().iterator().next()
                .getMessage();
    } 

} 

There must be some missing validation. How to validate HTTP GET properly with Spring Boot

Answer

john picture john · Oct 7, 2019

I have an excellent (IMHO) solution with Jsoup and Apache Commons. I Hope it will help other people

Add this class

import org.apache.commons.lang.StringEscapeUtils;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

public class SecurityEscape {

    public static String cleanIt(String arg0) {
        return Jsoup.clean(
                StringEscapeUtils.escapeHtml(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeSql(arg0)))
                , Whitelist.basic());
    }


} 

Now you can clean all incoming strings from GET or POST like this in your controller

    @PostMapping("/api/blah") or GET whatever . .. . .  .
    public ResponseEntity<?> testIt(String whatever) { 

String whatever = SecurityEscape.cleanIt(whatever); 

... .. 

AFTER THIS CHECKMARX SAYS THIS IS A SAFE CODE

Special thanks to @Sabir Khan for guidance