如何使用Spring Boot验证和清理HTTP Get?

时间:2019-01-01 08:12:37

标签: validation spring-boot http-get checkmarx

我一直从Checkmarx代码扫描器中收到这个烦人的错误,

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. 

这是我的代码。我想我做了所有必要的验证。还有什么?

@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();
    } 

} 

必须缺少一些验证。如何使用Spring Boot正确验证HTTP GET

4 个答案:

答案 0 :(得分:2)

使用这些扫描工具时,您需要格外小心,因为有时这些工具报告误报,有时不需要更改代码。我不是checkmarx的专家,但是请确保该工具确实了解您正在使用的bean验证批注以及调用Jsoup.clean(personName, Whitelist.basic())

  

我认为我已进行了所有必要的验证。还有什么?

首先,您需要了解控制器的应用程序级别输入卫生和业务级别输入验证之间的区别。您在这里所做的是第二部分,第一部分可能是您设置中缺少的,而这完全是出于安全性的考虑,通常是针对整个应用程序进行设置。

您正在使用@Size批注来限制输入的大小,但这不能保证坏字符串-可能导致XSS攻击的字符串。然后,您正在使用调用Jsoup.clean(personName, Whitelist.basic()))来清理此已验证大小的输入。由于我不确定该调用的作用,因此您需要确保新值是XSS-Safe。您会立即将该值传递给数据库调用,然后将Integer返回给调用者/客户端,因此我对这里发生XSS攻击的可能性非常悲观,但是工具却这么说。

  

必须缺少一些验证。如何验证HTTP GET   使用Spring Boot可以正常使用

正如我之前解释的那样,输入验证是一个通常用于业务逻辑级别输入验证的术语,而输入清理/清理是关于安全性的。在Spring Boot环境中,这通常是通过使用 Spring Security API 并启用XSS过滤器或编写自己的XSS过滤器并将其插入应用程序来完成的。首先是筛选器,然后是控制器,因此控制器将始终具有经过净化的价值,并且您将对该经过净化的价值进行业务验证。

这是一个广泛的答案和代码,您可能会用google。还建议阅读更多有关XSS攻击的信息。只需了解有多种方法可以实现相同的目标。

3 Ways to Prevent XSS

XSS prevention in Java

How to create filter in Spring RESTful for Prevent XSS?

Cross Site Scripting (XSS) Attack Tutorial with Examples, Types & Prevention

最后一个链接中提到的

  

防止这种攻击的第一步是输入验证。   用户输入的所有内容均应经过精确验证,   因为用户的输入可能会找到通往输出的方式。

&,您没有在代码中执行此操作,因此我猜没有XSS。

编辑:

XSS安全性有两个方面-首先,不允许对服务器端代码进行恶意输入,这可以通过使用XSS过滤器来完成;有时,允许恶意输入没有任何危害(假设您保存了该恶意输入到数据库或返回API响应)。

第二个方面是指示HTML客户端可能的XSS攻击(如果我们确定API客户端将是HTML / UI的话),那么我们需要添加X-XSS-Protection标头,这可以通过以下代码完成。这将使浏览器可以打开其XSS保护功能(如果有)。

@Override 受保护的void configure(HttpSecurity http)引发异常{

http.headers().xssProtection()....

}

What is the http-header “X-XSS-Protection”?

Is Xss protection in Spring security enabled by default?

第一个方面,即编写过滤器-请参考my this answer和该答案中的链接。

我想,我在上面错误地写道,Spring Security提供了输入卫生过滤器,我猜是没有。将会验证并告知您。我已经在回答该问题的那行写了我的自定义过滤器-Prevent XSS in Spring MVC controller

您还必须了解,Spring Boot也习惯于编写传统的MVC应用程序,其中服务器端也提供HTML来呈现。对于JSON响应(REST API),UI客户端可以控制要转义的内容和不进行转义的内容,因此会产生复杂性,因为JSON输出并不总是馈送到HTML客户端(也就是浏览器)。

答案 1 :(得分:1)

我使用Jsoup和Apache Commons提供了出色的(IMHO)解决方案。希望对其他人有帮助

添加此类

myObj2.myProp.length; // error!

现在您可以在控制器中像这样从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()); } } GET清除所有传入的字符串

POST

此CHECKMARX表示这是安全代码

特别感谢@Sabir Khan的指导

答案 2 :(得分:1)

这对Checkmarx v8.8.0也很有效

offendingValue = StringEscapeUtils.escapeHtml(offendingValue);

顺便说一句,我在https://github.com/mehditahmasebi/spring/blob/master/spring-xss-filter/src/main/java/com/spring/boot/web/WebConfig.java上尝试了成功的解决方案

答案 3 :(得分:0)

这对我有用 ----

import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.apache.commons.lang3.StringEscapeUtils;
import org.springframework.util.StringUtils;

public class SecurityUtil {

    private SecurityUtil() {
        throw new IllegalStateException("Utility class");
    }

    /**
     *  Remove escape characters like Html/Js scripts from input if present
     * @param str Input string
     * @return sanitize string
     */
    public static String cleanIt(String str) {
        return Jsoup.clean(
                StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript (StringUtils.replace(str, "'", "''")))
                , Whitelist.basic());
    }
}