🛡️ Sentinel: [CRITICAL/HIGH] Upgrade token encryption to AES-GCM (#117)
Upgraded `encodeAssetId` and `decodeAssetId` to use `aes-256-gcm` (Authenticated Encryption) instead of `aes-256-cbc`. AES-CBC lacks authentication, leaving it potentially susceptible to padding oracle attacks or ciphertext manipulation. The new token adds a `v2:` prefix which strictly enforces AES-GCM while supporting legacy fallback for cached urls. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
@@ -18,12 +18,11 @@ describe('tokens', () => {
|
||||
});
|
||||
|
||||
describe('encodeAssetId', () => {
|
||||
it('produces a non-empty base64url string', () => {
|
||||
it('produces a non-empty string with v2: prefix', () => {
|
||||
const token = encodeAssetId(SAMPLE_UUID);
|
||||
expect(token).toBeTruthy();
|
||||
expect(typeof token).toBe('string');
|
||||
// base64url characters only
|
||||
expect(token).toMatch(/^[A-Za-z0-9_-]+$/);
|
||||
expect(token).toMatch(/^v2:[A-Za-z0-9_-]+$/);
|
||||
});
|
||||
|
||||
it('is deterministic — same input yields same token', () => {
|
||||
@@ -46,6 +45,20 @@ describe('tokens', () => {
|
||||
expect(decoded).toBe(SAMPLE_UUID);
|
||||
});
|
||||
|
||||
it('round-trips a legacy aes-256-cbc token', async () => {
|
||||
// Manually encode using legacy method
|
||||
const crypto = await import('crypto');
|
||||
const authSecret = 'test-auth-secret-32-chars-long-min';
|
||||
const key = crypto.createHash('sha256').update(authSecret).digest();
|
||||
const iv = crypto.createHash('sha256').update(SAMPLE_UUID).digest().subarray(0, 16);
|
||||
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
|
||||
const encrypted = Buffer.concat([cipher.update(SAMPLE_UUID, 'utf8'), cipher.final()]);
|
||||
const legacyToken = Buffer.concat([iv, encrypted]).toString('base64url');
|
||||
|
||||
const decoded = decodeAssetId(legacyToken);
|
||||
expect(decoded).toBe(SAMPLE_UUID);
|
||||
});
|
||||
|
||||
it('returns null for a garbage string', () => {
|
||||
expect(decodeAssetId('not-a-valid-token')).toBeNull();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user