15

JWTs typically include an audience claim. I've read in many places (articles, code examples, the spec itself) that you must check that the token is intended for you and not another audience.

I'm happy enough to accept that. I'm not planning on building anything that sends to JWTs to the wrong audience. But I'm curious as to why it's important to reject it.

You should be able to verify that the token was issued by an authentication server that you trust. So you have to accept that the claims in there are not fabricated.

The only risk I can think off is if the auth server produced different values, for the same claim, to different audiences. Other than poor namespacing, I can't think of a reason this would happen.

E.g.

{
  "aud": "foo",
  "roles": ["admin"]
}

Instead of:

{
  "aud": "foo",
  "foo.roles": ["admin"]
}

Perhaps the question could be better phrased as:

What bad things can happen if I accept another audience's (valid) JWT token?

Andy N
  • 442
  • 3
  • 12
  • Thinking aloud from scanning the link (I've not used JWTs): a company's finance system might have different "principals" for Order Entry and Payroll. Someone might be given a token with an audience of "OrderEntry" that shouldn't allow them to do anything in the Payroll part of the software. – TripeHound May 01 '19 at 10:49
  • @TripeHound - from my understanding the JWT (OIDC ones anyway) isn't intended to provide authorisation, only authentication. So the JWT tells you who the user is (in the form of various claims) and it's up to the apps to determine what they want to let them do. E.g. Maybe they have a particular role, or perhaps they're from a particular group or country. – Andy N May 01 '19 at 11:00

2 Answers2

13

Suppose I regularly use JWTs from AUTH SERVER to sign in to several several websites, including A and B. Without the aud claim, the JWTs would be identical. This would allow a malicious admin from A to use my JWT to authenticate to B.

Irfan434
  • 719
  • 5
  • 7
  • Just to double-check: are you just concurring with my namespacing point (i.e. A and B were allowed to name their claims identically) or is this a separate issue? – Andy N May 01 '19 at 13:39
  • In OIDC, "roles" is not a required claim. Authentication is perfectly valid without it. Hence, it is not safe to rely on role namespaces to prevent the type of attack I mentioned. – Irfan434 May 01 '19 at 14:02
  • No, of course not. All I'm saying is that systems sometimes use claims (role or otherwise) to determine level of access. Just because a user turns up with a JWT doesn't mean they get access. Or, to your point. How would B mistake an admin for A for one of it's own? – Andy N May 01 '19 at 14:43
  • 1
    When the end-user uses the same token for both A and B, A knows what the token is, and could pretend to be the end-user to B. – Irfan434 May 01 '19 at 16:19
  • 1
    Your apps should not rely on audience to control access. Each app should have a unique security context where the roles of users are validated uniqely – LastTribunal May 16 '22 at 23:10
8

I would argue that in a sense you are correct in that there's nothing special about the audience claim that you couldn't handle yourself through namespaced claims and custom security checks.

The JWT specifications notes that the aud claim (as well as the other registered claims) are optional and that the application needs should define when to use or not use them.

As to why it's commonly advised to authenticate on audience, it's basically a simple and standardized way to test whether the incoming JWT is meant for your application. It can be a hassle to create namespaced tokens for each and every application you want the identity to work for. Following the standard approach also makes things easier if you need to integrate with 3rd party apps or identity services.

The only real danger I can think of is if you or the next developer forget to do any additional checks that are now necessary due to not using audience checking.

AlphaD
  • 873
  • 6
  • 11
  • Marked as correct. But just a quick question - what sort of additional checks are you referring to? The 3 normal ones would be: [Valid signature, non-expired, audience]. If we drop the 3rd but keep the first 2 wouldn't that still be enough to know the claims were true? – Andy N May 02 '19 at 11:08
  • @AndyN I was just thinking that with your scheme you would want to check the claim list to make sure you don't get misshaped JWTs since you don't have the standard names with the namespace. You can also of course authenticate against the other standard claims such as issuer. As you say though a valid signature and expiry check would be the practical bare minimum. – AlphaD May 02 '19 at 11:26
  • Microsoft implores you to validate AUD and reject tokens that dont match your app, but they fail to provide a reason.. The problem with OAUTH protocol is that there are too many OAUTH Nazis that tell you what you must and must not do, without explaination. You make a simple case why there is no compulsion to rely on AUD – LastTribunal May 16 '22 at 23:13