0

I am trying to implement CSRF in a Struts 6.2.0 project.

struts.xml

<package name="struts-security" abstract="true" extends="struts-default">
  <interceptors>
    <interceptor-stack name="defaultSecurityStack" />
    
    <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor" />
    <interceptor name="tokenSessionStore" class=  "org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />
  </interceptors>

  <default-interceptor-ref name = "defaultSecurityStack" />

  <global-results>
    <result name="error">/error401.jsp</result>
  </global-results>

  <global-exception-mappings>
    <exception-mapping result="error" exception="java.lang.Exception" />
  </global-exception-mappings>

LoginAction.java

@Namespace("/common")
@Action("Login")
@InterceptorRefs({
  @InterceptorRef("token"),
  @InterceptorRef("tokenSessionStore")
})
@Results({
  @Result(name = "input", location = "login.Login", type = "tiles"),
})

login.jsp

<%@ taglib prefix="s" uri="/struts-tags"%>
  <s:form  method="post" validate="true" theme="simple" name="form" id="paraFrm" >
    <s:token />

It is returning invalid.token. Because I have added return page, it is redirecting to error page. Is there any requirement of additional code to implement token in action page or any other places.

Roman C
  • 49,761
  • 33
  • 66
  • 176

1 Answers1

0

To use the interceptor defined in the struts.xml you should add the annotation

@ParentPackage("struts-security")

You were trying to use a

tokenSession interceptor:

This interceptor builds off of the TokenInterceptor, providing advanced logic for handling invalid tokens. Unlike the normal token interceptor, this interceptor will attempt to provide intelligent fail-over in the event of multiple requests using the same session. That is, it will block subsequent requests until the first request is complete, and then instead of returning the invalid.token code, it will attempt to display the same response that the original, valid action invocation would have displayed if no multiple requests were submitted in the first place.

Example code:


<action name="someAction" class="com.examples.SomeAction">
    <interceptor-ref name="tokenSession"/>
    <interceptor-ref name="basicStack"/>
    <result name="success">good_result.ftl</result>
</action>

<-- In this case, myMethod of the action class will not
       get checked for invalidity of token -->
<action name="someAction" class="com.examples.SomeAction">
    <interceptor-ref name="tokenSession">
        <param name="excludeMethods">myMethod</param>
    </interceptor-ref name="tokenSession>
    <interceptor-ref name="basicStack"/>
    <result name="success">good_result.ftl</result>
</action>

As you see in the examples you were missing some basic interceptors.


These interceptors are defined in the struts-default package which is inherited. So, you shouldn't override them. Just remove these interceptors from the <interceptors> tag, or use <intetceptor-ref> tag instead. Only one token interceptor should be configured to the action. Because both is using the same token from the browser, so they are mutually exclusive.

<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor" />
<interceptor name="tokenSessionStore" class=  "org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />

Also check this answer if you want to create a custom interceptor stack and use it to every action.

Roman C
  • 49,761
  • 33
  • 66
  • 176