fix(auth): isolate bounded OIDC cleanup
This commit is contained in:
@@ -8,7 +8,8 @@ const MAX_PROTOCOL_BYTES = 64 * 1024;
|
||||
const MAX_RESPONSE_BYTES = 64 * 1024;
|
||||
const MAX_SESSION_BYTES = 16 * 1024;
|
||||
const MAX_OIDC_BYTES = 8 * 1024;
|
||||
const MAX_ENTRIES = 256;
|
||||
const DEFAULT_MAX_ENTRIES = 256;
|
||||
const MAX_ENTRIES = 512;
|
||||
const TIMEOUT_MS = 5_000;
|
||||
const DIGEST_FILENAME = /^[a-f0-9]{64}\.json$/;
|
||||
const CLAIM_FILENAME = /^[a-f0-9]{64}\.claim$/;
|
||||
@@ -29,7 +30,11 @@ export interface WindowsAuthStorageBridge {
|
||||
read(root: string, directory: WindowsAuthStorageDirectory, filename: string): Promise<Buffer | undefined>;
|
||||
replace(root: string, directory: WindowsAuthStorageDirectory, filename: string, contents: Buffer): Promise<void>;
|
||||
remove(root: string, directory: WindowsAuthStorageDirectory, filename: string): Promise<boolean>;
|
||||
list(root: string, directory: WindowsAuthStorageDirectory): Promise<WindowsAuthStorageEntry[]>;
|
||||
list(
|
||||
root: string,
|
||||
directory: WindowsAuthStorageDirectory,
|
||||
maximumEntries?: number,
|
||||
): Promise<WindowsAuthStorageEntry[]>;
|
||||
claimConsume(root: string, filename: string): Promise<Buffer | undefined>;
|
||||
readClaim(root: string, filename: string): Promise<Buffer | undefined>;
|
||||
removeClaim(root: string, filename: string): Promise<boolean>;
|
||||
@@ -98,6 +103,7 @@ interface BridgeRequest {
|
||||
directory: WindowsAuthStorageDirectory;
|
||||
filename?: string;
|
||||
contentBase64?: string;
|
||||
maximumEntries?: number;
|
||||
}
|
||||
|
||||
function directoryMaximum(directory: WindowsAuthStorageDirectory): number {
|
||||
@@ -151,7 +157,10 @@ function encodedRequest(request: BridgeRequest): Buffer {
|
||||
validateRoot(request.root);
|
||||
if (request.operation === "list") {
|
||||
if (request.filename !== undefined || request.contentBase64 !== undefined) throw invalid();
|
||||
if (request.maximumEntries !== undefined && (!Number.isInteger(request.maximumEntries)
|
||||
|| request.maximumEntries < 1 || request.maximumEntries > MAX_ENTRIES)) throw invalid();
|
||||
} else {
|
||||
if (request.maximumEntries !== undefined) throw invalid();
|
||||
if (request.filename === undefined) throw invalid();
|
||||
const allowClaim = request.operation === "remove" && request.directory === "oidc";
|
||||
const allowOidcSlot = request.directory === "oidc"
|
||||
@@ -350,9 +359,17 @@ export function createWindowsAuthStorageBridge(options: WindowsAuthStorageBridge
|
||||
const response = await request(recordRequest("remove", root, directory, filename));
|
||||
return response.removed === true;
|
||||
},
|
||||
async list(root, directory) {
|
||||
const response = await request({ version: PROTOCOL_VERSION, operation: "list", root, directory });
|
||||
async list(root, directory, maximumEntries = DEFAULT_MAX_ENTRIES) {
|
||||
if (!Number.isInteger(maximumEntries) || maximumEntries < 1 || maximumEntries > MAX_ENTRIES) throw invalid();
|
||||
const response = await request({
|
||||
version: PROTOCOL_VERSION,
|
||||
operation: "list",
|
||||
root,
|
||||
directory,
|
||||
maximumEntries,
|
||||
});
|
||||
if (response.entries === undefined) throw invalid();
|
||||
if (response.entries.length > maximumEntries) throw invalid();
|
||||
for (const entry of response.entries) {
|
||||
if (!DIGEST_FILENAME.test(entry.name) && !(directory === "oidc"
|
||||
&& (CLAIM_FILENAME.test(entry.name) || OIDC_SLOT_FILENAME.test(entry.name)))) throw invalid();
|
||||
|
||||
Reference in New Issue
Block a user