Non Canonical Header Key

ID

go.non_canonical_header_key

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Code Smell

Language

Go

Tags

CWE:1164, code-style, readability

Description

Reports a direct map-index access on an http.Header value whose string-literal key is not in canonical MIME form, for example h["etag"] or h["content-type"] = v.

Rationale

The net/http package stores header keys canonicalised — the first letter of each --separated word in upper case and the rest in lower case (for example "Etag", "Content-Type"). The accessor methods run each key through the standard canonicaliser before touching the underlying map, so a non-canonical key passed to them is harmless. Direct map indexing, however, bypasses that step and stores (or reads) the literal key exactly as written: h["etag"] = v is stored under "etag" and will never be found by code using the canonical "Etag". The rule fires only on direct indexing when the receiver resolves to net/http.Header and the key is a plain string literal whose canonical form differs from the written form; computed keys are left alone.

import "net/http"

func fn() {
    h := http.Header{}
    h["etag"] = v // FLAW — stored under non-canonical "etag", not "Etag"
    h["Etag"] = v // OK
}

Remediation

Write the header key in its canonical form, or use the http.Header accessor methods (Get / Set / Add / Del), which canonicalise the key for you.