Forcing 3xx Redirects
Many web servers enforce a canonical URL form, and the server often must resolve the resource before it can determine the canonical form and issue the redirect.
Mechanism: Many web servers enforce a canonical URL form — trailing slashes, case normalization, or path segment normalization. The server often must resolve the resource before it can determine the canonical form and issue the redirect. For non-existing resources, there's nothing to canonicalize — the server returns 404.
Common canonicalization patterns:
- Trailing slash enforcement:
/api/users/1001→301to/api/users/1001/(or vice versa) - Case normalization:
/API/Users/1001→301to/api/users/1001 - Index resolution:
/api/users/1001→301to/api/users/1001/index
Isolated Variable: Only the path format changes. Method, headers, body, and authentication remain identical.
Oracle Signal: 301/302 (exists, server redirects to canonical form) vs 404 (does not exist).
GET — Existing Resource (Trailing Slash Added)
GET /api/users/1001/ HTTP/1.1
Host: target.com
Authorization: Bearer valid-token
HTTP/1.1 301 Moved Permanently
Location: /api/users/1001
Content-Type: text/html
<html><body>Moved to /api/users/1001</body></html>GET — Non-Existing Resource (Trailing Slash Added)
GET /api/users/9999/ HTTP/1.1
Host: target.com
Authorization: Bearer valid-token
HTTP/1.1 404 Not Found
Content-Type: application/json
{"error": "Not Found"}GET — Existing Resource (Wrong Case)
GET /API/USERS/1001 HTTP/1.1
Host: target.com
Authorization: Bearer valid-token
HTTP/1.1 301 Moved Permanently
Location: /api/users/1001GET — Non-Existing Resource (Wrong Case)
GET /API/USERS/9999 HTTP/1.1
Host: target.com
Authorization: Bearer valid-token
HTTP/1.1 404 Not Found
Content-Type: application/json
{"error": "Not Found"}💡
Locationheader as a secondary oracle: TheLocationheader reveals the server's canonical URL. Different resource types may have different canonical forms — comparingLocationvalues across resource IDs reveals resource type or category.
💡 Route-level vs resource-level redirects: Some redirects happen at the route level (all paths get normalization regardless of the specific resource) and produce no oracle. Test by comparing: if both valid and invalid IDs redirect, the redirect is route-level. If only valid IDs redirect, the oracle is confirmed.
💡 Double-slash and dot-segment normalization: Beyond trailing slashes, test:
/api/users//1001,/api/users/1001/./profile,/api/users/1001/../1001,/api/users/1001%2Fprofile. Each is a potential oracle if the server resolves the resource before normalizing.
Mitigation: Perform path canonicalization at the routing layer before resource resolution. Return the same redirect (or the same 404) for both existing and non-existing resources under the same route pattern.