# Hostname normalization mismatch in security checks

Security checks comparing hostnames or cookie domains without matching case, IDN, or trailing-dot normalization

_Area: Web infrastructure and server-side requests. Seen in 4 disclosed reports; one confirmed bounty: $2,540; latest 2023-12-22. Updated 2026-10-23._

## How it works
A security decision (is this cookie domain a public suffix? is this host HSTS-protected?) compares a hostname against a reference list or stored state. The guard only works if both sides are in the same canonical form. When one side is lowercased, IDN-encoded, or dot-stripped and the other is not, the comparison misses, the guard is skipped, and the request or cookie is treated as trusted. The broken assumption is "both sides of the comparison are canonicalized identically." This shows up in three sub-mechanisms: static-list lookup (case), state keying (write vs read), and check-vs-use stage (which hostname representation the check sees).

## Where it shows up
- Cookie `Domain=` validation against the Public Suffix List or any static allow/block list.
- HSTS store/lookup keyed by hostname, especially where write and read paths differ.
- Code that lowercases, punycodes, or strips trailing dots on one path but not another.
- Mixed-case entries in an otherwise lowercase list (e.g. `co.UK` vs `co.uk`).
- Unicode dot variants (U+3002) or IDN hostnames reaching a policy check before conversion.
- Trailing-dot or percent-encoded hostnames reaching enforcement.

## How to review
Grep for PSL and HSTS lookup call sites and diff the normalization applied at each. For every hostname/domain comparison, confirm one canonicalization function (lowercase, IDN/punycode, dot normalization) runs on both input and reference before comparing. Trace write and read paths of HSTS and cookie stores separately and check they agree. The invariant: the string used for the security decision must be byte-identical to the string used for the actual connection or cookie scope.

## Variants seen
- Case-sensitive PSL comparison: `domain=co.UK` bypasses the public-suffix guard, planting a supercookie [E1](https://bugbountylibrary.com/r/h1%3A2274981.md).
- HSTS stored IDN-encoded but looked up IDN-decoded, so U+3002 hostnames skip HSTS [E2](https://bugbountylibrary.com/r/h1%3A1813831.md).
- HSTS checked on the raw pre-IDN hostname while the connection uses the ASCII host [E3](https://bugbountylibrary.com/r/h1%3A1753226.md).
- HSTS cache keyed inconsistently with trailing dots, so a trailing-dot URL bypasses HSTS [E4](https://bugbountylibrary.com/r/h1%3A1565622.md).

## Why fixes fail
HSTS IDN bypasses recurred across releases: E3 and E2 are follow-ups to earlier IDN HSTS fixes, each closing one normalization axis while another remained [E2](https://bugbountylibrary.com/r/h1%3A1813831.md)[E3](https://bugbountylibrary.com/r/h1%3A1753226.md).

## Impact and severity
Supercookies sent to unrelated sites and HSTS bypass forcing cleartext HTTP, enabling tracking and downgrade. Severity rises when the bypass is silent and spans shared infrastructure, and worsens when one normalization gap affects multiple features (cookies, HSTS, allowlists).

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A2274981.md
- E2: https://bugbountylibrary.com/r/h1%3A1813831.md
- E3: https://bugbountylibrary.com/r/h1%3A1753226.md
- E4: https://bugbountylibrary.com/r/h1%3A1565622.md
