首页 > 解决方案 > 如何使用 Spring Boot 验证和清理 HTTP Get?

问题描述

我不断从 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

标签: validationspring-boothttp-getcheckmarx

解决方案


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

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

首先,您需要了解控制器的应用程序级输入卫生和业务级输入验证之间的区别。您在这里所做的是第二部分,第一部分可能会在您的设置中丢失,这完全是从安全角度完成的,通常是为整个应用程序设置的。

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

一定有一些缺失的验证。如何使用 Spring Boot 正确验证 HTTP GET

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

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

防止 XSS 的 3 种方法

Java中的XSS预防

如何在 Spring RESTful 中创建过滤器以防止 XSS?

包含示例、类型和预防的跨站点脚本 (XSS) 攻击教程

在最后一个链接中,它提到了,

预防这种攻击的第一步是输入验证。用户输入的所有内容都应该经过精确验证,因为用户的输入可能会找到输出。

& 你没有在你的代码中做,所以我猜没有 XSS。

编辑:

XSS 安全性有两个方面 - 首先不允许恶意输入到服务器端代码,这将通过 XSS 过滤器来完成,有时,允许恶意输入没有害处(假设您将恶意输入保存到 DB 或在 API 响应中返回)。

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

@Override protected void configure(HttpSecurity http) 抛出异常 {

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

}

什么是 http-header “X-XSS-Protection”?

Spring 安全中的 Xss 保护是否默认启用?

对于第一方面,即编写过滤器 - 请参阅我的这个答案和那个答案中的链接。

我想,我在上面写错了 Spring Security 提供输入卫生过滤器,我猜,它没有。将验证并让您知道。我已经在回答这个问题时提到的行中编写了我的自定义过滤器-Prevent XSS in Spring MVC controller

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


推荐阅读