What Is a URL? Structure, Components, and Security Implications
A foundational guide to URLs: scheme, host, path, query parameters, fragment, and how attackers abuse URL parsing discrepancies.
Short answer
A URL (Uniform Resource Locator) is an address that tells a browser exactly where to find a resource and how to access it. Every URL is a structured string with several distinct parts, and attackers exploit ambiguities in how those parts are parsed by different systems.
The idea in one minute
Think of a URL as a mailing address on an envelope. The scheme is the shipping method. The host is the city and building. The port is a specific room. The path is the mailbox inside. The query string is a sticky note with instructions. The fragment is a note written for yourself that the courier never sees.
The problem: different postal services read the same address differently. One reads "New York, NY 10001" and sees the city as "New York." Another reads "10001" as a room number inside the building. These parsing disagreements let attackers craft addresses that look safe to one reader but point somewhere dangerous to another.
How a URL is structured
scheme://user:password@host:port/path?query#fragment
https://admin:secret@nyxeara.vip:443/learn?page=1#intro breaks down as: scheme https, user info admin:secret, host nyxeara.vip, port 443, path /learn, query page=1, fragment intro. The user info component is particularly dangerous: https://nyxeara.vip@evil.com — one parser sees nyxeara.vip as the destination, another correctly resolves to evil.com.
How URLs are parsed
A browser splits at :// for the scheme, then at the last @ for user info, then at : for host and port, then at ? for path and query, then at # for the fragment. The fragment is stripped before the HTTP request is ever sent — the server never sees it.
A minimal example
import requests
from urllib.parse import urlparse
def is_safe_url(url):
return "nyxeara.vip" in url # vulnerable: string matching
user_url = "https://nyxeara.vip@evil.com/steal"
if is_safe_url(user_url): # True — "nyxeara.vip" is in the string
requests.get(user_url) # Actually goes to evil.com
The fix: parse the URL and check only the hostname. String matching is not URL validation.
Why the parsing gap exists
URL parsers in browsers, HTTP libraries, and validation code implement RFC 3986 with significant differences. Percent encoding, international domain names, IPv6 addresses in brackets, empty host components, and default port handling all vary across implementations. A validator that accepts http://127.0.0.1 in one parser may reject it in another — or vice versa. These gaps are the root cause of SSRF, open redirect, and CRLF injection vulnerabilities.
What attackers look for
Any parameter that looks like it holds a URL: url=, redirect=, next=, dest=, path=, return=, callback=, image=. Features described as "import from URL," "preview," "validate this URL," or "fetch from" are prime candidates. Attackers supply alternate encodings, decimal IP representations, the @ character for authority confusion, and file/gopher/dict schemes to probe URL validation logic.
Detection
Supply unusual URLs in every URL-shaped parameter: http://evil@trusted, https://127.0.0.1#@trusted, file:///etc/passwd, decimal IPs, IPv6 variants, and percent-encoded schemes. Watch for redirects to unvalidated destinations or content from internal IPs.
Verification: real vulnerability or false positive?
Does the application parse the URL or just string-match? A check like url.includes("trusted.com") is trivially bypassed. If the application uses a proper parser, test whether the allowlist can be bypassed with alternate encodings or redirect chains. Confirm the redirect actually fires — a parameter that accepts a URL but sanitizes it before use is not a vulnerability.
Real-world impact
URL parsing bugs cause SSRF (reaching internal cloud metadata endpoints from an image-fetch feature), open redirect phishing (a ?next= parameter forwards to an attacker page after login), and CRLF injection (encoded newlines in a URL smuggle HTTP headers). The 2019 Capital One breach used an SSRF chain where a URL parameter was the entry point.
Prevention
Parse the URL with a proper parser and validate only the hostname component — never string-match. Normalize before validating. Restrict allowed schemes to https://. Use an allowlist, not a blocklist. For server-side fetches, validate the resolved IP at connection time to prevent DNS rebinding.
Related vulnerabilities
- SSRF — URL validation gaps let the server fetch internal resources
- Open redirect —
?url=parameter forwards to an attacker-controlled destination - CRLF injection — encoded newlines in a URL inject HTTP headers
- IDN homograph attacks — visually identical characters from different alphabets in domain names
Testing methodology (do this safely)
Test every URL-shaped parameter with scheme variations, authority confusion patterns, and alternate encodings. Verify redirect validators check the final resolved URL, not just the first hop. Test on your own applications or authorized bug bounty programs only.
Further reading
- MDN: What is a URL?
- WHATWG: URL Living Standard
- RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
- MITRE: CWE-20 — Improper Input Validation
Nyxeara perspective
URL parsing discrepancies are one of the most common root causes in web security findings. An SSRF bypass, open redirect, or CORS misconfiguration almost always traces back to the same mistake: checking whether a string contained a trusted domain instead of parsing the URL and validating only the hostname. The Nyxeara engine treats URL validation as a parser-comparison problem — attackers don't send strings, they send parsed structures, and the gap between the two is where vulnerabilities live.