'How to resolve XSRF Cross-Site Request Forgery (CSRF) in API controller after SAST Checkmarx
I have done the scan my project java spring boot with Checkmarx tool. The tool found about 23 XSRF occurrences with Medium severity.
The issue found is marked on Rest API method POST on @RequestBody List<String> lineups
In attached the screen-shoot for description result:
@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;
}
Is there sample fix to resolve the issue ?
Solution 1:[1]
You can choose to have a validation on that field. Here you have two choices:
- use a framework that has this already build in, i recommend spring for this: https://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html
- try to whitelist what strings you want to accept on your api, if you can do that.
The second one means you take the responsibility to keep your list up to date.
Solution 2:[2]
I tried to implement the first point that you told in your answer like followed code
Back-end side:
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();
}
}
Front-end side
I implemented a xhrRequestHandler file name js inside the followed code:
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');
}
};
and on the index.jsp
I imported file js defined above with the followed code:
<script src="<c:url value="/resources/js/xhrRequestHandler.js"/>"></script>
And added meta names rows:
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
but I didn't resolve the issue
Is there something wrong ?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Opri |
Solution 2 |