Search code examples
alfrescocsrfalfresco-share

Workflow admin console doesn't work: Possible CSRF attack noted


What I have:

Alfresco Share v5.2.d (r134641-b15, Aikau 1.0.101.3, Spring Surf 5.2.d, Spring WebScripts 6.13, Freemarker 2.3.20-alfresco-patched, Rhino 1.7R4-alfresco-patched, Yui 2.9.0-alfresco-20141223)

Alfresco Community v5.2.0 (r134428-b13) schema 10005

I want to use the workflow admin console. The console is available by link: http://....:8080/alfresco/s/admin/admin-workflowconsole

I'd like to be able to view all process definitions, delete the definition of the process, etc.

For example:

show definitions all
undeploy definition ...
use definition ...

etc

After accessing the console I try to execute any command, but get this exception (copy from screen):

HTTP Status 500 - Possible CSRF attack noted when comparing token in session and request parameter. Request: POST /alfresco/s/admin/admin-workflowconsole

type Exception report

message Possible CSRF attack noted when comparing token in session and request parameter. Request: POST /alfresco/s/admin/admin-workflowconsole

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Possible CSRF attack noted when comparing token in session and request parameter. Request: POST /alfresco/s/admin/admin-workflowconsole
    org.springframework.extensions.webscripts.servlet.CSRFFilter$AssertTokenAction.run(CSRFFilter.java:845)
    org.springframework.extensions.webscripts.servlet.CSRFFilter.doFilter(CSRFFilter.java:312)
    org.alfresco.web.app.servlet.GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:68)

How to configure workflow admin console?

What I was trying to do:

As written by Axel Faust,

The web-client-security-config.xml has a default configuration for the CSRFPolicy segment and can be overriden via the web-scripts-config-custom.xml file in the alfresco/extension path.

Thus, I created the file web-scripts-config-custom.xml, then added to it missing rule and placed it under the path /opt/alfresco-community/tomcat/shared/classes/alfresco/exten‌​sion:

<alfrescoco-config>
   <config evaluator="string-compare" condition="CSRFPolicy" replace="true">
      <filter>
         <rule>
            <request>
               <method>GET</method>
               <path>/service/admin/.*</path>
            </request>
            <action name="generateToken">
               <param name="session">{token}</param>
               <param name="cookie">{token}</param>
            </action>
         </rule>
         <rule>
            <request>
               <method>GET</method>
               <path>/s/admin/.*</path>
            </request>
            <action name="generateToken">
               <param name="session">{token}</param>
               <param name="cookie">{token}</param>
            </action>
         </rule>
      </filter>
   </config>
</alfresco-config>

It doesn't work...

I added full configuration:

<alfresco-config>

   <!--
      CSRF filter config to mitigate CSRF/Seasurfing/XSRF attacks

      To disable the CSRF filter override the <filter> to not contain any values, for example:
         <config evaluator="string-compare" condition="CSRFPolicy" replace="true">
            <filter/>
         </config>

      @since 5.2
   -->
   <config evaluator="string-compare" condition="CSRFPolicy">

      <!--
         Force creation of a Session when the filter matches a path - this should only be used when you are
         confident the filtered part of the web application is using an authentication mechanism that will avoid
         protected pages being accessed until the user is authenticated. Otherwise this would be a route to
         a Session fixation attack.
      -->
      <session>true</session>

      <!--
         Properties that may be used inside the rest of the CSRFPolicy config to avoid repetition but
         also making it possible to provide different values in different environments.
         I.e. Different "Referer" & "Origin" properties for test & production etc.
         Reference a property using "{propertyName}".
      -->
      <properties>

         <!-- There is normally no need to override this property -->
         <token>alf-csrftoken</token>

         <!--
            Override and set this property with a regexp that if you have placed Alfresco behind a proxy that
            does not rewrite the Referer header.
         -->
         <referer></referer>

         <!--
            Override and set this property with a regexp that if you have placed Alfresco behind a proxy that
            does not rewrite the Origin header.
         -->
         <origin></origin>
      </properties>

      <!--
        Will be used and exposed to the client side code in Admin.CSRF
        Use the Admin.CSRF.getHeader() or Admin.CSRF.getParameter() with Admin.CSRF.getToken()
        to set the token in custom 3rd party code.
      -->
      <client>
         <cookie>{token}</cookie>
         <header>{token}</header>
         <parameter>{token}</parameter>
      </client>

      <!-- The first rule with a matching request will get its action invoked, the remaining rules will be ignored. -->
      <filter>

         <!-- Refresh token on each new page visit -->
         <rule>
            <request>
               <method>GET</method>
               <path>/service/enterprise/admin/.*</path>
            </request>
            <action name="generateToken">
               <param name="session">{token}</param>
               <param name="cookie">{token}</param>
            </action>
         </rule>
         <rule>
            <request>
               <method>GET</method>
               <path>/s/enterprise/admin/.*</path>
            </request>
            <action name="generateToken">
               <param name="session">{token}</param>
               <param name="cookie">{token}</param>
            </action>
         </rule>
         <rule>
            <request>
               <method>GET</method>
               <path>/service/admin/.*</path>
            </request>
            <action name="generateToken">
               <param name="session">{token}</param>
               <param name="cookie">{token}</param>
            </action>
         </rule>
         <rule>
            <request>
               <method>GET</method>
               <path>/s/admin/.*</path>
            </request>
            <action name="generateToken">
               <param name="session">{token}</param>
               <param name="cookie">{token}</param>
            </action>
         </rule>

         <!--
            Verify multipart requests contain the token as a parameter
            and also correct referer & origin header if available
         -->
         <rule>
            <request>
               <method>POST</method>
               <header name="Content-Type">multipart/.+</header>
            </request>
            <action name="assertToken">
               <param name="session">{token}</param>
               <param name="parameter">{token}</param>
            </action>
            <action name="assertReferer">
               <param name="referer">{referer}</param>
            </action>
            <action name="assertOrigin">
               <param name="origin">{origin}</param>
            </action>
         </rule>

         <!--
            Verify that all remaining state changing requests contain a token in the header and correct referer & origin headers
            if available. We "catch" all content types since just setting it to "application/json.*" since a webscript that doesn't
            require a json request body otherwise would be successfully executed using i.e."text/plain".
         -->
         <rule>
            <request>
               <method>POST|PUT|DELETE</method>
            </request>
            <action name="assertToken">
               <param name="session">{token}</param>
               <param name="header">{token}</param>
            </action>
            <action name="assertReferer">
               <param name="referer">{referer}</param>
            </action>
            <action name="assertOrigin">
               <param name="origin">{origin}</param>
            </action>
         </rule>
      </filter>

   </config>

</alfresco-config>

It doesn't work...

As described here, I added to the web.xml the following:

  <filter-mapping>
      <filter-name>CSRF Token Filter</filter-name>
      <url-pattern>/service/admin/*</url-pattern>
   </filter-mapping>

   <filter-mapping>
      <filter-name>CSRF Token Filter</filter-name>
      <url-pattern>/s/admin/*</url-pattern>
   </filter-mapping>

It doesn't work...

I tried to disable CSRF filter by the following way:

<alfresco-config>
    <config evaluator="string-compare" condition="CSRFPolicy" replace="true">
        <filter/>
    </config>
</alfresco-config>

It doesn't work...

How to configure workflow admin console?


Solution

  • Finally, I found my mistake!..

    Instead of the web-scripts-config-custom.xml I created web-script-config-custom.xml. I missed the letter 's'

    Now everything is OK.

    Thank you very much, Axel Faust!..