Each line gets three readings. A is the native URL() object in the browser you are using right now. B is a strict validator built from the RFC 3986 Appendix A grammar, with section 5.2 resolution, section 6.2 normalization and an RFC 9110 http(s) check. C is the Appendix B regular expression split, which takes any string. Nothing leaves this page.
Input
With escapes off, a backslash is a literal backslash. Lines longer than 8192 characters are refused with an error. Markers such as TAB SP BS U+FF47 show characters that would otherwise be invisible or easy to miss.
Results
Self test
Runs on every page load. HARD checks prove the RFC side of this page is implemented correctly; if any fails, the page says its results cannot be trusted. INFORMATIONAL checks measure the engine you are running, so their counts differ between browsers and are computed live.
Engine probes
Each probe states what the WHATWG URL Standard algorithm produces at the named anchor and what this engine actually returned. A deviation is information about the engine, not a failure of this page. Notation: BS is one U+005C backslash, TAB is one U+0009.
| Probe | Expression | Expected | This engine | Result | WHATWG anchor |
|---|
How to use it
- Audit an allowlist or SSRF guard. Paste the URLs your validator approved, one per line. Any row with a HOST SPLIT flag is a string where the host this browser connects to differs from a host another reader would extract. If your check uses a splitter and your fetch uses a WHATWG engine, that row is the bypass shape.
- Decide where to reject. Column B tells you whether a strict RFC 3986 check would have refused the string outright, and names the first offending code point and the grammar rule. Several of the strings that split hosts never pass a strict check at all.
- Check an http(s) gate. RFC 3986 is generic syntax, so http:/evil.com/ is a valid URI. The RFC 9110 line under column B says whether it is a valid http or https URI, and flags any userinfo.
- Compare normalizers and cache keys. The normalization steps in column B are RFC 3986 6.2.2.1, 6.2.2.2, 6.2.2.3 and, for http and https only, 6.2.3. A row that agrees only after normalization tells you which step your comparison needs.
- Test resolution. Put a base URL in the base field and relative references in the box. Column B resolves them with RFC 3986 5.2.2; the strict toggle switches the scheme loophole described in 5.4.2.
- Know your engine. The self test runs the 42 RFC 3986 section 5.4 examples through this browser's
URL()and lists every mismatch live, and the probe table checks eleven parser rules. Run the page in each browser you ship to.
Result labels: AGREE AGREE AFTER RFC NORMALIZATION SAME IP, DIFFERENT TEXT DISAGREE RFC REJECTS, BROWSER ACCEPTS BROWSER FAILS, RFC ACCEPTS BOTH REJECT. Every colour is paired with its text label.
Sources and scope
RFC 3986 (STD 66, January 2005): rfc-editor.org/rfc/rfc3986, sections 2.3, 3.2, 3.2.2, 4.1, 5.2, 5.4, 6.2.2, 6.2.3, 7.4, Appendix A and Appendix B. This page implements the published RFC 3986 text; errata are not applied. RFC 9110 (STD 97, June 2022): rfc-editor.org/rfc/rfc9110, sections 4.2.1, 4.2.2 and 4.2.4. WHATWG URL Standard (a Living Standard): url.spec.whatwg.org, anchors #concept-basic-url-parser, #authority-state, #special-authority-ignore-slashes-state, #port-state, #concept-ipv4-parser, #ends-in-a-number-checker, #double-dot-path-segment, #forbidden-host-code-point and #special-scheme. WHATWG behaviour is paraphrased, never quoted.
RFC 3986 quotations and the 42 reference resolution vectors are from RFC 3986, Copyright (C) The Internet Society (2005). RFC 9110 quotations are from RFC 9110, Copyright (c) 2022 IETF Trust and the persons identified as the document authors. Behaviour is implemented from the published specifications; no code is reproduced here. IRIs (RFC 3987) are out of scope: any non-ASCII code point makes a string invalid under RFC 3986.
This is an independent tool. It is not affiliated with, or endorsed by, the WHATWG, the IETF or any browser vendor.