cybersecurity · intermediate · ~25 min

Extract the host from a URL safely

Strict URL host extraction with explicit reject rules.

Challenge

Extract just the host from a URL with a strict, conservative parser — URL parsing is a notorious CVE source, and writing one teaches what vetted libraries reject and why.

Task

Implement int extract_host(const char *url, char *out_host, size_t cap) that copies the host into out_host, NUL-terminated and capped to cap-1 bytes.

Input

  • url: a NUL-terminated URL of the form scheme://host[:port][/path][?query][#fragment]. The grader passes fixed strings.
  • out_host, cap: the output buffer and its capacity.

Output

Returns int: 1 on success (writing the host), or 0 on any failure.

Example

extract_host("http://example.com/foo")          ->   1, out_host = "example.com"
extract_host("https://api.example.com:8443/v1") ->   1, out_host = "api.example.com"
extract_host("http://127.0.0.1")                ->   1, out_host = "127.0.0.1"
extract_host("file:///etc/hosts")               ->   0   (empty host)
extract_host("not-a-url")                        ->   0   (no ://)
extract_host("http://user:pw@evil/foo")          ->   0   (userinfo refused)

Edge cases

  • Missing scheme or missing :// returns 0.
  • An empty host returns 0.
  • A host that does not fit in out_host returns 0.

Rules

  • The host starts after :// and ends at the first /, :, ?, #, or end of string.
  • Refuse (return 0) any URL containing userinfo (user:pass@host) — a known XSS/SSRF vector — rather than parsing it.
  • No external parsers; pure C scanning with a cap-aware copy.

Why this matters

URL parsing is a notorious source of security bugs (CVEs in nginx, curl, browsers). Real production code uses a vetted library. But understanding the structure — and writing a strict, conservative parser — teaches you what those libraries are doing and why they reject so many edge cases.

Input format

A NUL-terminated url, an output buffer out_host, and its capacity cap.

Output format

An int: 1 with the host in out_host, or 0 on any failure.

Constraints

url is null-terminated string; out receives host with capacity cap.

Starter code

#include <stddef.h>
int extract_host(const char *url, char *out_host, size_t cap) { /* TODO */ return 0; }

Common mistakes

Buffer overflow when host exceeds cap or reading past end of string.

Edge cases to handle

Missing scheme, empty host, host with port, URL without path.

Complexity

O(strlen(url)).

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.