auth-backend: refuse to issue excessively large tokens

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-02-01 12:19:38 +01:00
parent 021a500fa0
commit a9e0107111
3 changed files with 35 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
The auth backend will now refuse to issue user tokens are excessively large.
@@ -154,6 +154,23 @@ describe('TokenFactory', () => {
}).rejects.toThrow();
});
it('should refuse to issue excessively large tokens', async () => {
const factory = new TokenFactory({
issuer: 'my-issuer',
keyStore: new MemoryKeyStore(),
keyDurationSeconds: 5,
logger,
});
await expect(() => {
return factory.issueToken({
claims: { sub: 'user:ns/n', ent: Array(10000).fill('group:ns/n') },
});
}).rejects.toThrow(
/^Failed to issue a new user token. The resulting token is excessively large, with either too many ownership claims or too large custom claims./,
);
});
it('should defaults to ES256 when no algorithm string is supplied', async () => {
const keyDurationSeconds = 5;
const factory = new TokenFactory({
@@ -23,6 +23,7 @@ import { LoggerService } from '@backstage/backend-plugin-api';
import { AnyJWK, KeyStore, TokenIssuer, TokenParams } from './types';
const MS_IN_S = 1000;
const MAX_TOKEN_LENGTH = 32768; // At 64 bytes per entity ref this still leaves room for about 500 entities
type Options = {
logger: LoggerService;
@@ -97,7 +98,8 @@ export class TokenFactory implements TokenIssuer {
throw new AuthenticationError('No algorithm was provided in the key');
}
return new SignJWT({ ...additionalClaims, iss, sub, ent, aud, iat, exp })
const claims = { ...additionalClaims, iss, sub, ent, aud, iat, exp };
const token = await new SignJWT(claims)
.setProtectedHeader({ alg: key.alg, kid: key.kid })
.setIssuer(iss)
.setAudience(aud)
@@ -105,6 +107,16 @@ export class TokenFactory implements TokenIssuer {
.setIssuedAt(iat)
.setExpirationTime(exp)
.sign(await importJWK(key));
if (token.length > MAX_TOKEN_LENGTH) {
throw new Error(
`Failed to issue a new user token. The resulting token is excessively large, with either too many ownership claims or too large custom claims. You likely have a bug either in the sign-in resolver or catalog data. The following claims were requested: '${JSON.stringify(
claims,
)}'`,
);
}
return token;
}
// This will be called by other services that want to verify ID tokens.