AWS Authorizer - Possible Caching Issue?

We are seeing some odd behavior with AWS API Gateway and Auth0 Authorizers. We are getting random 403 errors back from our APIs(Lambdas).

We can hit an API and get a 200 back. Then, seconds later, we are getting a 403 out of the blue.

{“Message”:“User is not authorized to access this resource”}

Doing some digging around, it sounds similar to this issue:
https://forums.aws.amazon.com/thread.jspa?threadID=225934&tstart=0

However, I don’t think that post is using Auth0, but I am not 100% sure.

Has anybody experienced something similar?

Your issue sounds familiar. Let me explain the issue I had a while ago maybe it helps you.

I used the custom authorizer and in API Gateway and disabled the Cache. In spite of that it cached the authorize request!

I was sending GET and POST to the same resource. First time that I send a GET the request, it worked fine. Any GET request would work fine but I couldn’t send a POST request for that resource. If I would wait for few minutes and send a POST, it would work again but this time GET had problem.

I solved this issue by changing the returned policy. Each time I send back the policy I allow both GET and POST for that resource. If this change doesn’t make any vulnerability on your system you can try it.

Thanks, @armanfatahi! When you say “send back the policy I allow both GET and POST for that resource”, is that done on the API Gateway or somewhere else?

It’s done in the custom authorizer.

The custom authorizer checked the access_token and creates a policy. Then return the policy to API Gateway.

If you are using the custom authorizer Auth0 introduced, you should see this in the lib.js:

    jwt.verify(token, signingKey, { audience: process.env.AUDIENCE, issuer: process.env.TOKEN_ISSUER },
        function (err, decoded) {
            if (err) {
                cb(err);

            }
            else {

                cb(null, {
                    principalId: decoded.sub,
                    policyDocument: getPolicyDocument('Allow', params.methodArn),
                    context: {
                        scope: decoded.scope
                    }
                });
            }
        });

I changed this code to:

    ...
    jwt.verify(token, signingKey, { audience: process.env.AUDIENCE, issuer: process.env.TOKEN_ISSUER },
        function (err, decoded) {
            if (err) {
                cb(err);

            }
            else {

                cb(null, {
                    principalId: decoded.sub,
                    policyDocument: getPolicyDocument('Allow',  "*";),
                    context: {
                        scope: decoded.scope
                    }
                });
            }
        });

Which means if the user is authorized, allow using the whole API resources, this includes GET and POST for each resource.

1 Like

Thanks a lot for sharing it with the rest of community!

I have been struggling with this issue for a few days now…
Thanks for the solution @armanfatahi

1 Like

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.