Analysis of CSRF principles and Struts2 token verification Defense Strategy

Source: Internet
Author: User
Tags csrf attack

Analysis of CSRF principles and Struts2 token verification Defense Strategy
Struts2 token not only effectively prevents repeated form submission, but also supports CSRF verification.
The CSRF attack principle is as follows:


CSRF attack schematic


In fact, B may also be a benign website, but it is only hijacked by the hacker XSS. The user is really wronged: I have not got a mess of websites, why is it still a trick?
Struts2 token Verification Principle:


Struts2 token verification schematic


According to the CSRF attack schematic, although. jsp returns the token value to the browser, But B cannot get the specific value of the token, or B can only get A token by requesting, however, the purpose of forging user requests is lost because the session is inconsistent. Therefore, B. action no longer processes the forged request. The CSRF process is truncated, as shown in:


Struts2 token truncated the CSRF attack schematic


If you understand the principles, let's work. It is found that many non-form submission requests are successfully intercepted, for example, the original ajax requests, href requests on the page, and dwr requests cannot work normally. -- remove the token verification of the actions in these requests to work normally, however, this gives hackers a good opportunity.
So how can I transfer struts2 token to other requests except the form?
Let's continue to learn more about the struts2 token verification principles.

Take the latest version 2.3.20 as an example. Add an action in struts. xml In fact, the org. apache. struts2.interceptor. TokenInterceptor interceptor is configured. View its doIntercept source code:

 

protected String doIntercept(ActionInvocation invocation) throws Exception {if (log.isDebugEnabled()) {log.debug(Intercepting invocation to check for valid transaction token.);}//see WW-2902: we need to use the real HttpSession here, as opposed to the map//that wraps the session, because a new wrap is created on every requestHttpSession session = ServletActionContext.getRequest().getSession(true);synchronized (session) {if (!TokenHelper.validToken()) {return handleInvalidToken(invocation);}}return handleValidToken(invocation);}

 

It calls the validToken method of org. apache. struts2.util. TokenHelper. Its source code is as follows:
public static boolean validToken() {String tokenName = getTokenName();if (tokenName == null) {if (LOG.isDebugEnabled()) {LOG.debug(no token name found -> Invalid token );}return false;}String token = getToken(tokenName);if (token == null) {if (LOG.isDebugEnabled()) {LOG.debug(no token found for token name +tokenName+ -> Invalid token );}return false;}Map session = ActionContext.getContext().getSession();String sessionToken = (String) session.get(tokenName);if (!token.equals(sessionToken)) {if (LOG.isWarnEnabled()) {LOG.warn(LocalizedTextUtil.findText(TokenHelper.class, struts.internal.invalid.token, ActionContext.getContext().getLocale(), Form token {0} does not match the session token {1}., new Object[]{token, sessionToken}));}return false;}// remove the token so it won't be used againsession.remove(tokenName);return true;}

It first calls its own getTokenName () to get the tokenName value, and then uses its own getToken (tokenName) to get the value of the token parameter requested by the client, finally, compare it with the value saved in the session.
View the getTokenName () source code:
public static String getTokenName() {Map params = ActionContext.getContext().getParameters();if (!params.containsKey(TOKEN_NAME_FIELD)) {if (LOG.isWarnEnabled()) {LOG.warn(Could not find token name in params.);}return null;}String[] tokenNames = (String[]) params.get(TOKEN_NAME_FIELD);String tokenName;if ((tokenNames == null) || (tokenNames.length < 1)) {if (LOG.isWarnEnabled()) {LOG.warn(Got a null or empty token name.);}return null;}tokenName = tokenNames[0];return tokenName;}

TOKEN_NAME_FIELD is a static variable of org. apache. struts2.util. TokenHelper with the value of struts. token. name. The function of the getTokenName method is to get the value of struts. token. name passed by the client. After the validToken obtains this value, it continues to call getToken based on this value. The getToken source code:
public static String getToken(String tokenName) {if (tokenName == null ) {return null;}Map params = ActionContext.getContext().getParameters();String[] tokens = (String[]) params.get(tokenName);String token;if ((tokens == null) || (tokens.length < 1)) {if (LOG.isWarnEnabled()) {LOG.warn(Could not find token mapped to token name  + tokenName);}return null;}token = tokens[0];return token;}

It is based on the value of the struts. token. name parameter, for example, token (this value can be configured in the token tag of jsp, such , The default value is token), get the value of the token parameter sent from the client, and finally return it to the validToken method.
The struts action with token verification captured by chrome's developer tool confirms the above statement:


The value of struts. token. name intercepted


I have understood the principles, and the following things seem to have gone through.
$. Ajax supports struts2 token:
<script>var strutsToken = 
  ;var token = {  struts.token.name: token,  token: strutsToken};$.ajax({  url: '/endpoint',  data: token,  dataType: 'jsonp',  cache: true,  success: function() { console.log('success'); },  error: function() { console.log('failure'); }});</script>

The href request on the page supports struts2 token:
Title = Edit Meta> View Details


 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.