fix: bind stalwart auth context to credential, not cookie-claimed username

This commit is contained in:
Linus Rath
2026-05-18 13:00:40 +02:00
parent f134766fd1
commit f275fbe2e4
3 changed files with 42 additions and 10 deletions
+25
View File
@@ -40,6 +40,31 @@ export function validateProxyAuthHeader(authHeader: string): void {
}
}
/**
* For a `Basic` Authorization header, assert that the user portion of the
* credentials matches `claimedUsername`. Prevents callers of routes that
* accept independent `username` + `authHeader` fields from binding a cookie
* to one identity while authenticating as another. No-op for Bearer.
*/
export function assertBasicAuthMatchesUsername(authHeader: string, claimedUsername: string): void {
const match = /^Basic\s+(\S+)$/i.exec(authHeader);
if (!match) return;
let decoded: string;
try {
decoded = Buffer.from(match[1], 'base64').toString('utf8');
} catch {
throw new JmapAuthVerificationError('Invalid Authorization header', 400);
}
const colon = decoded.indexOf(':');
if (colon < 0) {
throw new JmapAuthVerificationError('Invalid Authorization header', 400);
}
const credUser = decoded.slice(0, colon);
if (credUser !== claimedUsername) {
throw new JmapAuthVerificationError('Username does not match credentials', 400);
}
}
export async function verifyJmapAuth(
serverUrl: string,
authHeader: string,