postgrest-docs icon indicating copy to clipboard operation
postgrest-docs copied to clipboard

Document more explicitly that a token without `aud` will still be accepted with a `jwt-aud` setting

Open robertsosinski opened this issue 4 years ago • 3 comments

Environment

  • PostgreSQL version: 13.1
  • PostgREST version: v9.0.0 docker postgrest/postgrest:v9.0.0
  • Operating system: Windows 10, Running PostgREST/PostgreSQL via Docker

Description of issue

I have PostgREST running with a jwt-aud config set via Docker with PGRST_JWT_AUD to testing456. I've tried four things; and the fourth one is where I think there is a bug.

  1. JWT with "aud": [], an empty aud, fails with JWTNotInAudience, which is correct.
  2. JWT with "aud": ["testing123"], the wrong aud, fails with JWTNotInAudience, which is correct.
  3. JWT with "aud": ["testing123, testing456"], with the correct aud, succeeds, which is correct.
  4. JWT without an "aud" parameter, and thus the correct aud of testing456 is not defined, succeeds; which I think should fail; right?

It looks like if you specify PostgREST with an jwt-aud, but generate JWTs without an "aud" field, they still have access to the server anyway. I would expect once PostgREST specifies jwt-aud in the config; it must be in the JWT to provide access.

Is this required according to the JWT spec? I am planning on having a lot of PostgREST servers running; and if I accidently generate a JWT without an "aud" field it would have wide ranging access.

Thanks!

robertsosinski avatar Dec 18 '21 05:12 robertsosinski

The RFC says, that the aud parameter is optional:

The interpretation of audience values is generally application specific. Use of this claim is OPTIONAL.

Our docs say this:

jwt-aud

Specifies the JWT audience claim. If this claim is present in the client provided JWT then you must set this to the same value as in the JWT, otherwise verifying the JWT will fail.

I don't really see a violation of the RFC and the docs describe this also just like you describe it. I don't see a bug here.

wolfgangwalther avatar Dec 18 '21 09:12 wolfgangwalther

Thanks for the response @wolfgangwalther. I assumed that when PostgREST specifies an jwt-aud, the JWT would also need to specify that aud to be valid. Perhaps having one of the "red boxes" in the docs explicitly calling that out would help as this behavior still caught me by surprise. Interested in how others think.

Anyhoo, I was able to solve this by adding the following in my pre-request function with the following:

if current_setting('request.jwt.claims', true)::json ->> 'aud' is null then
    raise insufficient_privilege using detail = 'Invalid aud', hint = 'Your session does not represent a valid aud.';
end if;

I could see this behavior being usefull to allow for 'blank-check, non-aud` JWTs as well as allowing applications to specify more constrained access if they desire.

Thanks!

robertsosinski avatar Dec 18 '21 17:12 robertsosinski

I could see this behavior being usefull to allow for 'blank-check, non-aud` JWTs as well as allowing applications to specify more constrained access if they desire.

Yeah, I guess that's the idea here.

I assumed that when PostgREST specifies an jwt-aud, the JWT would also need to specify that aud to be valid. Perhaps having one of the "red boxes" in the docs explicitly calling that out would help as this behavior still caught me by surprise.

That sounds like a good idea - I'll transfer this to the docs repo to keep track of this suggestion there.

wolfgangwalther avatar Dec 23 '21 22:12 wolfgangwalther