fix: reject control characters in manifest URLs

This commit is contained in:
2026-07-20 18:02:16 +02:00
parent bc0135e528
commit 187871aae4
7 changed files with 152 additions and 8 deletions

View File

@@ -0,0 +1,9 @@
export function containsAsciiControl(value: string): boolean {
for (const character of value) {
const codePoint = character.codePointAt(0);
if (codePoint !== undefined && (codePoint <= 0x1f || codePoint === 0x7f)) {
return true;
}
}
return false;
}

View File

@@ -14,6 +14,7 @@ import {
type ToolboxRequirements,
type ToolboxSource,
} from "./types.js";
import { containsAsciiControl } from "./ascii.js";
type UnknownRecord = Record<string, unknown>;
@@ -108,6 +109,10 @@ function referenceAt(
): string | undefined {
const value = stringAt(object, key, path, issues, { optional });
if (value === undefined) return undefined;
if (containsAsciiControl(value)) {
issues.push(`${path}.${key} must not contain ASCII control characters`);
return undefined;
}
if (value.includes("\\")) {
issues.push(`${path}.${key} must use URL path separators`);
return undefined;

View File

@@ -6,6 +6,7 @@ import {
type ResolvedToolboxPrivacy,
type ToolboxAppManifest,
} from "./types.js";
import { containsAsciiControl } from "./ascii.js";
const WEB_PROTOCOLS = new Set(["http:", "https:"]);
@@ -13,6 +14,15 @@ export function resolveWebUrl(
reference: string | URL,
base?: string | URL,
): URL {
if (
(typeof reference === "string" && containsAsciiControl(reference)) ||
(typeof base === "string" && containsAsciiControl(base))
) {
throw new ToolboxError(
"invalid-url",
"URL strings must not contain ASCII control characters",
);
}
let url: URL;
try {
url = base === undefined ? new URL(reference) : new URL(reference, base);