4
votes

Problem Overview:

We are upgrading our system from CQ5.4 to AEM 6.1. In the existing code we have referred to POST.jsp using ajax, where we are invoking Authentication services to authenticate an external user to the system. We are getting the below error when we do an ajax post to the resource POST.jsp. in the error.log. com.adobe.granite.csrf.impl.CSRFFilter doFilter: the provided CSRF token is invalid

What have we tried:

  1. To fix this we tried the solution as per AEM 6.1 docs https://docs.adobe.com/docs/en/aem/6-1/administer/security/security-checklist.html#par_title_1046104842.
    But it didn't worked.
  2. We tried removing POST from the filter methods in Adobe Granite CSRF Filter configuration from system/console/configMgr. This worked but this affects the security of our system since it allows other external system to POST data. (Correct me if I sam wrong on security)
  3. We tried adding google chrome browser user agent in the Safe User Agents in Adobe Granite CSRF Filter configuration from system/console/configMgr. This worked but the application can be used from various other user agents which we cannot keep on whitelisting in the Safe User Agents.

Also we decomplied the com.adobe.granite.csrf.impl.CSRFFilter and found the below code:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain Chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest)req;
    if ((request.getAuthType() != null) && (isFilteredMethod(request)) && (doFilterBasedOnUserAgent(request)) && (!isValidRequest(request))) {
        HttpServletResponse response = (HttpServletResponse)res;

        this.logger.info("doFilter: the provided CSRF token is invalid");
        response.sendError(403);
        return;
    }
    chain.doFilter(req, res);
}

In the above code, The isFilteredMethod checks if the current request(POST) is present in the configured filtered methods of Adobe Granite CSRF Filter.
The doFilterBasedOnUserAgent checks if the current request's User Agent is absent in the configured User agents.
request.getAuthType is "FORM" in our case. So this will not lead to (403).

The isValidRequest gets the request param :cq_csrf_token and checks if this parameter value is valid. (Observed this and is valid in our case and sends the parameter)

So what is the significance of filtered methods and user agents ? and why does CSRF sends 403 for POST.jsp although all CQ and AEM 5.x versions support this way of POSTING request?

2
Can you please let me know what was the fix you put?Sumanta Pakira

2 Answers

2
votes

so there are couple of things you can do-

  1. use cq.jquery clientlib for jquery instead of manually creating and including a jquery lib. aem provided jquery has code to handle csrf token.
  2. include granite.csrf.standalone clientlib in your code. it will do the stuff for you.
  3. you can manually get the value for the token from /libs/granite/csrf/token.json. send this value with every request in CSRF-Token header.
0
votes

alternatively you can filter your own servlet under 'Adobe Granite CSRF Filter configuration' instead of allowing all POST requests or above using cq jquery.