-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
Category: security
Severity: patch
File(s): src/core/GltfLoader.ts (validateExternalUri)
Description
The strict-mode allowlist regex /^[A-Za-z0-9._\-/]+$/ is applied to both the raw URI and its decoded form via candidates.every(…). For typical inputs this is benign, but the regex engine on some JS runtimes exhibits non-linear backtracking when the input contains many alternating allowed/disallowed characters (e.g. a 10 000-character string of a.). Since validateExternalUri is called inside resolveBuffers for every buffer entry in a glTF asset, a malformed asset can trigger this in a loop.
Problematic code example
// src/core/GltfLoader.ts — validateExternalUri
if (strict && !candidates.every((v) => /^[A-Za-z0-9._\-/]+$/.test(v))) {
throw new Error(…);
}Suggested fix
Add an explicit length cap before running the regex to bound execution time regardless of input content.
const MAX_URI_LENGTH = 2048;
if (strict) {
if (candidates.some((v) => v.length > MAX_URI_LENGTH)) {
throw new Error(`Buffer ${bufferIndex}: URI exceeds maximum allowed length in strict mode.`);
}
if (!candidates.every((v) => /^[A-Za-z0-9._\-/]+$/.test(v))) {
throw new Error(…);
}
}Acceptance criteria
- A URI length cap (e.g. 2048 characters) is enforced before the strict-mode regex runs
- A unit test confirms that a URI longer than the cap is rejected in strict mode
- Non-strict mode is unaffected
Reactions are currently unavailable