如何在 SAST Checkmarx 之后解决 API 控制器中的 XSRF 跨站请求伪造 (CSRF)
Posted
技术标签:
【中文标题】如何在 SAST Checkmarx 之后解决 API 控制器中的 XSRF 跨站请求伪造 (CSRF)【英文标题】:How to resolve XSRF Cross-Site Request Forgery (CSRF) in API controller after SAST Checkmarx 【发布时间】:2021-07-08 08:49:33 【问题描述】:我已经使用 Checkmarx 工具扫描了我的项目 java spring boot。 该工具发现了大约 23 个中等严重性的 XSRF 事件。
发现的问题标记在@RequestBody List<String> lineups
上的 Rest API 方法 POST 上
附上描述结果的截图:
@RequestMapping(value = "/rules/lineup/ruleMode", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> getRulesByRuleModeAndLineup(@PathVariable Integer ruleMode,
@RequestBody List<String> lineups) throws Exception
LOGGER.info("[getRulesByRuleModeAndLineup] ENTER type: " + ruleMode + " lineup: " + lineups);
ResponseEntity<Object> output = null;
List<Rule> rules = new ArrayList<Rule>();
try
for (String lineup : lineups)
String lineupSanitized = htmlUtils.htmlEscape(lineup);
rules.addAll(uiService.getRulesByRuleModeAndLineup(ruleMode, lineupSanitized));
output = new ResponseEntity<>(rules, HttpStatus.OK);
catch (Exception e)
LOGGER.error(e, e);
output = new ResponseEntity<>("An error occurred: " + e.getMessage() + "'",
HttpStatus.INTERNAL_SERVER_ERROR);
return output;
是否有解决问题的示例修复程序?
【问题讨论】:
该消息似乎很好地解释了这个问题:有一个用户提供的参数似乎在该方法中使用不安全。如何安全使用它或丢弃错误?只有你可以知道,因为只有你可以看到处理它的方法的源代码。如果您不向我们展示该代码,那么读者将无能为力。 【参考方案1】:您可以选择对该字段进行验证。 在这里你有两个选择:
-
使用已经内置的框架,我推荐 spring
为了这:
https://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html
尝试将您希望在您的 api 上接受的字符串列入白名单,如果您
可以做到。
第二个意味着你有责任保持你的列表是最新的。
【讨论】:
【参考方案2】:我试图实现你在回答中所说的第一点,比如后面的代码
后端端:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
private static final Logger LOGGER = LogManager.getLogger(SecurityConfig.class);
@SuppressWarnings("javadoc")
@Override
protected void configure(HttpSecurity http) throws Exception
http.authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated();
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
http.headers().httpStrictTransportSecurity();
前端端
我在后面的代码中实现了一个xhrRequestHandler文件名js:
XMLHttpRequest.prototype.origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function ()
this.origOpen.apply(this, arguments);
if (document.cookie)
var csrfToken = document.cookie.match(new RegExp(`XSRF-TOKEN=([^;]+)`))[1];
if (csrfToken)
this.setRequestHeader("X-XSRF-TOKEN", csrfToken);
if (arguments[1].includes("socket/info"))
this.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
;
在 index.jsp 上
我用下面的代码导入了上面定义的文件js:
<script src="<c:url value="/resources/js/xhrRequestHandler.js"/>"></script>
并添加元名称行:
<meta name="_csrf" content="$_csrf.token"/>
<meta name="_csrf_header" content="$_csrf.headerName"/>
但我没有解决问题
有什么问题吗?
【讨论】:
以上是关于如何在 SAST Checkmarx 之后解决 API 控制器中的 XSRF 跨站请求伪造 (CSRF)的主要内容,如果未能解决你的问题,请参考以下文章