Skip to content

Commit 80afb69

Browse files
fix(backend): Enforce azp when configured (#8877)
1 parent 6f97ef5 commit 80afb69

3 files changed

Lines changed: 25 additions & 3 deletions

File tree

.changeset/warm-spies-double.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/backend': patch
3+
---
4+
5+
Enforce the `azp` (authorized party) claim when `authorizedParties` is configured. Previously, a session token that was missing the `azp` claim was accepted even when `authorizedParties` was set, allowing the authorized-parties check to be bypassed by omitting the claim. Now, when `authorizedParties` is configured, a token with a missing or empty `azp` claim is rejected. Tokens without `azp` continue to be accepted when no `authorizedParties` are configured.

packages/backend/src/jwt/__tests__/assertions.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,21 @@ describe('assertSubClaim(sub?)', () => {
204204
});
205205

206206
describe('assertAuthorizedPartiesClaim(azp?, authorizedParties?)', () => {
207-
it('does not throw if azp missing or empty', () => {
207+
it('does not throw if azp missing or empty and no authorizedParties are configured', () => {
208208
expect(() => assertAuthorizedPartiesClaim()).not.toThrow();
209209
expect(() => assertAuthorizedPartiesClaim('')).not.toThrow();
210210
expect(() => assertAuthorizedPartiesClaim(undefined)).not.toThrow();
211+
expect(() => assertAuthorizedPartiesClaim('', [])).not.toThrow();
212+
expect(() => assertAuthorizedPartiesClaim(undefined, [])).not.toThrow();
213+
});
214+
215+
it('throws error if azp is missing or empty but authorizedParties are configured', () => {
216+
expect(() => assertAuthorizedPartiesClaim('', ['azp-1'])).toThrow(
217+
`Invalid JWT Authorized party claim (azp) "". Expected "azp-1".`,
218+
);
219+
expect(() => assertAuthorizedPartiesClaim(undefined, ['azp-1'])).toThrow(
220+
`Invalid JWT Authorized party claim (azp) undefined. Expected "azp-1".`,
221+
);
211222
});
212223

213224
it('does not throw if authorizedParties missing or empty', () => {

packages/backend/src/jwt/assertions.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,17 @@ export const assertSubClaim = (sub?: string) => {
8484
};
8585

8686
export const assertAuthorizedPartiesClaim = (azp?: string, authorizedParties?: string[]) => {
87-
if (!azp || !authorizedParties || authorizedParties.length === 0) {
87+
// When no authorized parties are configured there is nothing to enforce, so
88+
// an azp-less token is accepted (a warning is surfaced elsewhere).
89+
if (!authorizedParties || authorizedParties.length === 0) {
8890
return;
8991
}
9092

91-
if (!authorizedParties.includes(azp)) {
93+
// Once authorized parties are configured the azp claim must be present and
94+
// match one of them. Returning early on a missing/empty azp would let any
95+
// token bypass the authorized-parties check simply by omitting the claim,
96+
// defeating the purpose of configuring them.
97+
if (!azp || !authorizedParties.includes(azp)) {
9298
throw new TokenVerificationError({
9399
reason: TokenVerificationErrorReason.TokenInvalidAuthorizedParties,
94100
message: `Invalid JWT Authorized party claim (azp) ${JSON.stringify(azp)}. Expected "${authorizedParties}".`,

0 commit comments

Comments
 (0)