Validating a redirect target against an allowlist
Compare the parsed host, not a substring of the raw string. A check for 'example.com' matches evil-example.com.attacker.net; a host comparison does not.
Splits any URL into its parts: protocol, host, port, path, query, fragment and UTM parameters.
—Splits any URL into its parts: protocol, host, port, path, query, fragment and UTM parameters.
https://example.com/products?id=42&utm_source=google
protocol: https host: example.com path: /products query: id=42&utm_source=google utm_source: google
Every URL component is labeled.
Each component is shown separately so you can see exactly what the URL does.
Your input is sent to YAS infrastructure because the tool requires server-side processing or public network queries. Input is not stored.
curl -X POST "https://yas.sh/api/v1/tools/url-parser" \
-H "Content-Type: application/json" \
-d '{"input":"https://user:pass@example.com:8443/a/b?q=1#frag"}'const res = await fetch("https://yas.sh/api/v1/tools/url-parser", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"input": "https://user:pass@example.com:8443/a/b?q=1#frag"
}),
});
const data = await res.json();import requests
r = requests.post("https://yas.sh/api/v1/tools/url-parser", json={"input":"https://user:pass@example.com:8443/a/b?q=1#frag"})
data = r.json()| Field | Type | Required | Description |
|---|---|---|---|
| input | string | Yes | Any URL |
{ "result": { "protocol": "https:", "host": "example.com:8443", "hostname": "example.com", "port": "8443", "pathname": "/a/b", "query": { "q": "1" }, "hash": "#frag", "origin": "https://example.com:8443" } }Split any URL into protocol, auth, host, port, path, query (parsed), hash + origin.
400 VALIDATION_ERROR — invalid input or unsupported option.413 PAYLOAD_TOO_LARGE — input exceeds the 64 KB limit.429 RATE_LIMIT_EXCEEDED — rate limit exceeded (60 req/min).Parsing follows the WHATWG URL Standard, the same algorithm browsers use, which decomposes a URL into protocol, username, password, host, port, pathname, search and hash. It is deliberately more forgiving than RFC 3986: backslashes are normalised to forward slashes, tabs and newlines are stripped, the host is lowercased and IDNA-encoded to Punycode, and a default port matching the scheme is removed.
Those normalisation steps are where security bugs live. A URL that a naive parser reads as pointing to one host may be read by a browser as pointing to another — userinfo containing an @ symbol, unusual whitespace, or mixed encoding are all classic tricks for making a link look like it targets a trusted domain. Parsing with the same algorithm the client will use is the only reliable way to know the real destination.
Compare the parsed host, not a substring of the raw string. A check for 'example.com' matches evil-example.com.attacker.net; a host comparison does not.
Reading back the exact UTM values a partner used is faster than deciphering a long query string by eye, and it surfaces duplicated keys.
Trailing slashes, encoded characters and case in the pathname decide which route matches. Seeing the parsed pathname resolves the argument quickly.
Normalisation reveals internationalised or Punycode hosts that visually impersonate a legitimate domain.
What this tool deliberately does not do, and where it will disagree with other implementations.