---
title: "ADR-0009: One canonical target parser and a versioned address corpus"
manual: "HTTP Guard"
version: "main"
permalink: "https://docs.typo3.org/permalink/netresearch/nr-http-guard:adr-0009@main"
source: "Adr/ADR-0009-NormalizationAndAddressClasses.rst"
rendered: "2026-10-18T14:31:38+00:00"
---

# ADR-0009: One canonical target parser and a versioned address corpus {#adr-0009}

-   *Status:* Historical proposal (original status: Proposed)
-   *Date:* 2026-10-08
-   *Original decision makers:*

    Project architecture/security owners; approval
    still pending in the original proposal.

-   *Requirements:* HG-007, HG-008, HG-009, HG-010, HG-011, HG-012
-   *Original supersession:* None; a new decision for the proposed product.

> [!NOTE]
> This is the full English translation of the historical proposal dated
> 2026-10-08, originally Proposed. Its pending approval is historical and
> creates no additional alpha approval gate. Current
> [Security model and limits](https://docs.typo3.org/permalink/netresearch/nr-http-guard:security@main), [Development and tests](https://docs.typo3.org/permalink/netresearch/nr-http-guard:development@main), [Verification report](https://docs.typo3.org/permalink/netresearch/nr-http-guard:verification-report@main) and
> [Requirements and security invariants](https://docs.typo3.org/permalink/netresearch/nr-http-guard:development-requirements@main) describe the operative scope and evidence.
>
> The later single-package decision is recorded in [ADR-0015: One installable extension](https://docs.typo3.org/permalink/netresearch/nr-http-guard:adr-0015@main).

## Context {#adr-0009-context}

Parsers interpret noncanonical numeric addresses differently. The Host header
and URI may disagree. A coarse private-IP filter does not cover every local or
special address class. IANA maintains separate IPv4/IPv6 special-purpose
registries.

Sources: `[S04, S05, S10, S11]`.

## Decision {#adr-0009-decision}

The guard normalizes once, then uses a typed Target and applies the same
authority to transport. Absolute HTTP/HTTPS URLs are mandatory; userinfo,
fragments, control characters, zone IDs, host percent encoding and
noncanonical numeric forms are rejected. After normalization, HTTP Host and
URI authority must agree. Unicode hostnames are not implicitly converted in
v1; ASCII IDNA names already converted canonically are permitted.

IP and CIDR checks use binary representations for both families. IPv4-mapped
IPv6 is evaluated against the embedded IPv4 policy. Tunneling/translation
ranges are conservatively blocked. The versioned corpus names private ranges,
loopback, link-local, metadata relevance, multicast, documentation/benchmark
and other special ranges.

The v1 public policy is deliberately more conservative than merely accepting
the positive Globally-Reachable marking of individual special addresses.
Operator deny can additionally block nominally public ranges routed
internally. Registry updates are versioned, never downloaded live for every
request.

## Rejected alternatives {#adr-0009-rejected-alternatives}

-   **Regular expressions alone:** unsuitable for comprehensive IP/CIDR
    decisions.
-   **PHP filter flags alone:** implicitly couples policy to their particular
    runtime semantics.
-   **Private IPv4 without IPv6:** leaves a second address family open.
-   **Accept every parser correction:** increases interpretation differences.

## Consequences {#adr-0009-consequences}

There is one testable decision path and traceable dataset versions. Some
legitimate special addresses and Unicode inputs are restricted; callers must
supply canonical targets. A public IP still does not mean "a server whose
content is trustworthy".

## Evidence and acceptance in the original proposal {#adr-0009-verification-and-acceptance}

`T008, T009, T010, T011, T012, T013, T014, T015, T016, T017, T018, T019, T020, T021`.
Details and expected results are in [Original verification specification](https://github.com/netresearch/typo3_http_guard/blob/3f929ae8794ca04ab3dd25627e94d601a2db23e0/specification/specs/06-verification.md).
These tests were specified, not executed as part of the original documentation
delivery.

## Reasons to reconsider {#adr-0009-reassessment-trigger}

Relaxing a blocked address class or parser form requires a corpus change,
justification and boundary tests. New IANA entries are treated like
security-relevant dependency changes.

## Related documents {#adr-0009-related-documents}

[Original ADR](https://github.com/netresearch/typo3_http_guard/blob/3f929ae8794ca04ab3dd25627e94d601a2db23e0/specification/adr/ADR-0009-normalisierung-und-adressklassen.md), [Original product requirements](https://github.com/netresearch/typo3_http_guard/blob/3f929ae8794ca04ab3dd25627e94d601a2db23e0/specification/specs/01-product-requirements.md), [Original security model](https://github.com/netresearch/typo3_http_guard/blob/3f929ae8794ca04ab3dd25627e94d601a2db23e0/specification/specs/02-security-model.md),
[Original architecture](https://github.com/netresearch/typo3_http_guard/blob/3f929ae8794ca04ab3dd25627e94d601a2db23e0/specification/specs/03-architecture.md) and [Original source catalogue](https://github.com/netresearch/typo3_http_guard/blob/3f929ae8794ca04ab3dd25627e94d601a2db23e0/specification/specs/08-evidence-and-sources.md) (`S01-S23`),
plus the [ADR index](https://docs.typo3.org/permalink/netresearch/nr-http-guard:adr-index@main). [Original sources](https://docs.typo3.org/permalink/netresearch/nr-http-guard:adr-original-sources@main) explains
the immutable source index.
