summaryrefslogtreecommitdiff
path: root/workers/picker-test
diff options
context:
space:
mode:
authorYuriy Andamasov <yuriy@vyos.io>2026-07-28 05:36:57 +0300
committerYuriy Andamasov <yuriy@vyos.io>2026-07-28 05:36:57 +0300
commit0c9348035b583f3cd5fca72937a7ec1a61d7df45 (patch)
tree6113a587f5dbbe4b719ad2bbcd940f29395d89c3 /workers/picker-test
parentcfca705f325a073c00e221a080eff968112d7653 (diff)
downloadvyos-documentation-claude/vyos-docs-security-remediate-2cff61.tar.gz
vyos-documentation-claude/vyos-docs-security-remediate-2cff61.zip
security: normalize percent escapes per run, not per segmentclaude/vyos-docs-security-remediate-2cff61
Round-2 adversarial finding (Codex, medium): whole-segment decode meant one malformed escape (a%20b%zz) threw for the segment and double-encoded the valid escapes beside it. encodeSegment now decodes+re-encodes each well-formed %HH run independently; literal spans (including a bare '%') always pass through encodeURIComponent, so taint neutralization holds unconditionally; a run decoding to invalid UTF-8 stays verbatim (already pure %HH text). workers suite 108/108 (+2 discriminating regression tests). 🤖 Generated by [robots](https://vyos.io)
Diffstat (limited to 'workers/picker-test')
-rw-r--r--workers/picker-test/picker.test.ts14
1 files changed, 14 insertions, 0 deletions
diff --git a/workers/picker-test/picker.test.ts b/workers/picker-test/picker.test.ts
index 7d7594cc..560fd0d2 100644
--- a/workers/picker-test/picker.test.ts
+++ b/workers/picker-test/picker.test.ts
@@ -117,6 +117,20 @@ describe("URL construction percent-encodes hostile path components", () => {
for (const c of HOSTILE) expect(url).not.toContain(c);
});
+ // Normalization runs per %HH run, not per segment: a whole-segment decode throws on the
+ // malformed escape and then double-encodes the valid one beside it (a%2520b%25zz).
+ it("encodePath normalizes each escape run independently in a mixed-validity segment", () => {
+ const url = P.encodePath("a%20b%zz/x");
+ expect(url).toBe("a%20b%25zz/x");
+ for (const c of HOSTILE) expect(url).not.toContain(c);
+ });
+
+ it("encodePath keeps an invalid-UTF-8 escape run verbatim (already pure %HH text)", () => {
+ const url = P.encodePath("x%E0%A4y.html");
+ expect(url).toBe("x%E0%A4y.html");
+ for (const c of HOSTILE) expect(url).not.toContain(c);
+ });
+
it("targetUrlFor encodes a markup-injecting target slug", () => {
const url = P.targetUrlFor(loc, '"><img src=x>');
expect(url).toBe("/en/%22%3E%3Cimg%20src%3Dx%3E/cli/index.html");