cybersecurity · intermediate · ~20 min

Refuse a DNS result that resolves to an internal range (SSRF defence)

The SSRF allow-list pattern: refuse internal addresses.

Challenge

Refuse internal-range IPv4 addresses — the SSRF defence a public service applies after resolving a user-supplied URL, so it never fetches from its own private network.

Task

Implement int is_internal_ipv4(unsigned char a, unsigned char b, unsigned char c, unsigned char d) that returns 1 if the address a.b.c.d falls in any reserved range below, else 0.

Reserved ranges:

  • 10.0.0.0/8 (RFC 1918 private)
  • 127.0.0.0/8 (loopback)
  • 169.254.0.0/16 (link-local)
  • 172.16.0.0/12 (RFC 1918 private — second octet 16..31)
  • 192.168.0.0/16 (RFC 1918 private)
  • 224.0.0.0/4 (multicast — first octet 224..239)

Input

  • a, b, c, d: the four octets of an IPv4 address (each 0..255). The grader passes fixed values.

Output

Returns int: 1 if the address is in any reserved range, else 0.

Example

is_internal_ipv4(10, 0, 0, 1)      ->   1
is_internal_ipv4(172, 16, 0, 1)    ->   1
is_internal_ipv4(172, 31, 255, 255)->   1
is_internal_ipv4(172, 32, 0, 0)    ->   0   (just outside 172.16/12)
is_internal_ipv4(8, 8, 8, 8)       ->   0

Edge cases

  • 172.16/12 spans only second octets 16..31; 172.15.* and 172.32.* are external.
  • Multicast 224/4 covers first octets 224..239.

Rules

  • Pure arithmetic on the octets — no DNS or networking.

Why this matters

A web app that fetches a user-supplied URL is the textbook SSRF target. Resolving the host and refusing internal-range results closes the class.

Input format

Four octets a, b, c, d of an IPv4 address.

Output format

An int: 1 if the address is in a reserved/internal range, else 0.

Constraints

Pure logic; no DNS; mind the 172.16/12 (16..31) and 224/4 (224..239) boundaries.

Starter code

int is_internal_ipv4(unsigned char a, unsigned char b, unsigned char c, unsigned char d) { /* TODO */ (void)a; (void)b; (void)c; (void)d; return 0; }

Common mistakes

Forgetting 172.16/12 is only the 16..31 range of the second octet, not 16-32.

Edge cases to handle

Boundary: 172.16.0.0, 172.31.255.255, 172.32.0.0 (just outside). 224.0.0.0 multicast boundary.

Complexity

O(1).

Background lessons

Up next

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