security: round 3 hardening (CSRF double-submit, TRX MITM, container hardening)
This commit is contained in:
@@ -21,7 +21,7 @@ const ITSDANGEROUS_EPOCH = 1293840000; // 2011-01-01 UTC in unix time
|
||||
export interface CsrfConfig {
|
||||
secret: string;
|
||||
salt: string;
|
||||
digest: 'sha1' | 'sha256' | 'sha512';
|
||||
digest: 'sha256' | 'sha512';
|
||||
maxAgeSec: number;
|
||||
}
|
||||
|
||||
@@ -61,8 +61,9 @@ export async function fetchCsrfConfig(
|
||||
throw new Error('CSRF salt invalid: must be string >= 8 chars');
|
||||
}
|
||||
|
||||
let digest: 'sha1' | 'sha256' | 'sha512' = 'sha512';
|
||||
if (secrets.digest === 'sha1' || secrets.digest === 'sha256' || secrets.digest === 'sha512') {
|
||||
// sha1 deprecated — accept только sha256/sha512.
|
||||
let digest: 'sha256' | 'sha512' = 'sha512';
|
||||
if (secrets.digest === 'sha256' || secrets.digest === 'sha512') {
|
||||
digest = secrets.digest;
|
||||
}
|
||||
|
||||
@@ -87,8 +88,10 @@ function deriveKey(secret: string, salt: string, digest: string): Buffer {
|
||||
|
||||
function decodeTimestamp(encoded: string): number {
|
||||
const raw = b64urlDecode(encoded);
|
||||
// Использовать арифметику вместо bitwise — bitwise overflowит на 32-bit signed
|
||||
// после 2038 если timestamp encoding станет 5-байтным.
|
||||
let ts = 0;
|
||||
for (const b of raw) ts = (ts << 8) | b;
|
||||
for (const b of raw) ts = ts * 256 + b;
|
||||
return ts + ITSDANGEROUS_EPOCH;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user