Skip to content

lab-ops-hub: container validator still allows IDNA-disallowed Unicode hosts (space separators, bidi/format controls, U+FFFD) the Worker validator refuses #516

Closed

Description

@dezren39

Summary

While verifying the fix for #510, an extended character probe (beyond #510's battery of printable ASCII + 0x7F–0xA0 + é + a combining char) found a further divergence class between the two lab-ops-hub crawl validators: hosts containing certain Unicode characters are refused by the Worker's validateCrawlUrl (pkgs/lab-ops-hub/src/lib.ts — the WHATWG URL parser's IDNA processing rejects them) but are still certified as "a public DNS name" by the container's validate_crawl_url (pkgs/lab-ops-hub/container/app.py).

Verified on main 025794c8 (plus the #510 fix, which does not affect these codepoints) by driving both real validators with each character embedded as http://exam<char>ple.com/:

Codepoint(s) TS Worker Python container
U+1680, U+2000–U+200A, U+202F, U+205F, U+3000 (Unicode space separators) BLOCK ALLOW
U+2028, U+2029 (line/paragraph separators) BLOCK ALLOW
U+0600, U+061C (Arabic format marks) BLOCK ALLOW
U+200E, U+200F (LRM/RLM), U+202A–U+202E (bidi embedding/override controls) BLOCK ALLOW
U+200C, U+200D (ZWNJ/ZWJ in this context) BLOCK ALLOW
U+FFFD (replacement character) BLOCK ALLOW

Controls, identical on both sides (must not change): U+00AD (soft hyphen), U+180E, U+200B (ZWSP), U+2060, U+2064, U+FEFF are ALLOW/ALLOW; ordinary DNS names, exam_ple.com, valid IDN hosts (e.g. examéple.com) and valid IPv6 literals are ALLOW/ALLOW.

Why it matters

Same parity premise as #468/#502/#505/#507/#510: the container validator is the defence-in-depth re-check on the component that actually fetches (#441), so where the two validators disagree the effective policy is the weaker one. These hosts are not valid DNS names under UTS-46/IDNA either — no resolver accepts a host with a bidi override or an ideographic space in a label — so the container's verdict is meaningless for them and the crawl fails below the validator instead of at it.

This is a wider, IDNA-shaped class than the ASCII/codepoint-range fixes so far: a correct fix probably needs to judge the host label-by-label against the IDNA disallowed set (or attempt a strict UTS-46/IDNA encoding of each label and refuse on failure), not another codepoint range. Python's stdlib encodings.idna implements IDNA 2003, not UTS-46, so its verdicts need comparing against the WHATWG set before relying on it.

Acceptance criteria

  • validate_crawl_url refuses a host containing any of the codepoints in the table above, up front with a clear validator error.
  • Controls unchanged: the ALLOW/ALLOW codepoints in the table, ordinary DNS names, exam_ple.com, valid IDN hosts, valid IPv6 literals and public targets are still accepted on both sides.
  • A regression test in pkgs/lab-ops-hub/test/test_container_validate.py covers each refused class, and fails with only container/app.py reverted (ablation).
  • The Python and TS validators agree on the extended battery above (the table's codepoints plus the lab-ops-hub: container validator still allows DEL/C1-control, NBSP and WHATWG-forbidden (<>^|) hosts the Worker validator refuses #510 battery).

Cross-repo note: this validator pair lives only in developing-today/code (see #510's cross-repo check), so this is a single-repo issue.

Activity

  1. added a commit that references this issue on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions