Source reading · RFC 9110 · Fielding, Nottingham, Reschke 2022 · one standard read closely, with every claim tiered against what it actually requires

HTTP Semantics · STD 97 · June 2022

Every field in an HTTP message is a control surface or a leak.

This is a source reading, not a survey of web attacks. One document is the anchor, and the page's job is to separate what RFC 9110 requires from what the security folklore built on top of it merely assumes. Smuggling, cache poisoning, redirect-driven SSRF, IDOR, cross-site tracing, method-confusion bypasses: each is what happens when an implementation quietly disagrees with this text, and each is worth much less in a report if you cite the wrong sentence.

So every claim here carries a tier. Some of them are requirements you can hold a server to. Most are not, and a few of the most-repeated ones turn out to rest on sections that say something different. Those are marked where they appear rather than quietly dropped, because the correction is the interesting part.

Fielding R, Nottingham M, Reschke J, Eds. 2022. HTTP Semantics. STD 97, RFC 9110. datatracker.ietf.org/doc/html/rfc9110 · doi:10.17487/RFC9110

MUST the document states a requirement, in its own MUST or MUST NOT language. Deviation is a conformance violation and you can quote the sentence.

SHOULD / MAY normative but discretionary. An implementation may depart from it with reason, so the finding is real but weaker as a conformance claim.

Defined the RFC defines the semantics, or names the risk in §17, without requiring anything of the server at this point.

Field implementation behaviour. RFC 9110 neither requires nor predicts it, so the claim rests on practice, not on the document.

Not what 9110 says marks a place where the common retelling outruns the text. There are 30 of these on the page, and they are the reason it was worth reading the RFC rather than the cheat sheets.

One exchange

One state-changing request and its response, annotated field by field. Nothing here is exotic: it is the shape of an ordinary API call, and every line of it is either a control surface or a disclosure. Select a line to read what the document says about it and how far that reaches.

Request
Response

All twelve annotations are printed below. With scripting on, selecting a line shows just that one.

Method and request-target§9.3.4, §7.1MUST

PUT is unsafe and idempotent (§9.2.1, §9.2.2), which makes it the sharpest verb for testing whether authorization was wired for state-changing writes rather than only for reads. The path is its own probe: change the identifier.

Authority§7.2Defined

The most attacked field in the document, and the RFC says so. Because host and port act as an application-level routing mechanism, §7.2 calls it a frequent target for poisoning a shared cache or redirecting a request to an unintended server. Try a duplicate line, a trusted port suffix, an internal name.

Credentials§11.6.2Defined

§17.16.1 treats confidentiality of credentials as a live risk from the moment this field exists, because the framework provides none of its own. Whether the value survives a redirect to another origin is decided by the client, not by 9110.

Message framing§8.6MUST

The normative hook here is §5.4: a server that receives fields larger than it wishes to process MUST answer with a 4xx, because ignoring them would increase its vulnerability to request smuggling. The Content-Length versus Transfer-Encoding analysis itself belongs to RFC 9112.

Representation metadata§8.3Field

Swap it for XML or plain text against the same endpoint. Undocumented negotiated formats frequently reach a different, less hardened parser than the documented one.

Precondition§13.1.1Defined

The optimistic-concurrency guard. Strip it and send two writes concurrently. If both are accepted, the lost-update protection §8.8.1 describes was never actually in place.

Content§6.4Field

Mass-assignment target. Partial-update endpoints regularly accept and apply fields that no response schema advertises, which is a property of the framework rather than of HTTP.

Status line§15.3.1Field

A 200 rather than a 401 or 403 on a privileged write against a resource belonging to someone else is the entire finding. Pair it with the body diff to make impact unambiguous.

Response context§10.2.2Field

Confirms the identifier scheme is enumerable, which feeds straight back into the sweep on the request line above.

Validator§8.8.3Defined

A new validator issued after the write. The named concern in §17.14 is the reverse of enumeration: a tag that is unique per user and long-lived is a tracking identifier.

Content negotiation§12.5.5SHOULD / MAY

If this response also reflects an attacker-influenced field into cacheable content without naming it here, that is a cache-poisoning candidate. Generating Vary is a SHOULD, and §12.5.5 permits eliding it on performance grounds.

Field order exception§5.3MUST

§5.3 says a sender MUST NOT generate multiple field lines with the same name unless the field definition allows list recombination, then notes that Set-Cookie does exactly that in practice, violating the requirement, and that recipients ought to handle it as a special case because it cannot be combined into a single field value.

Methods

§9.2 gives every method two properties worth building a checklist around: safe, meaning the semantics are essentially read-only and the client neither requested nor expects a state change, and idempotent, meaning the intended effect of N identical requests matches the effect of one. Both describe intent rather than guaranteed server behaviour, and the RFC is explicit about that. The gap between the two readings is where the bugs live.

GET

§9.3.1

Transfer a current representation of the target resource.

MUST

State-changing GET is a spec violation, not just bad taste. §9.2.1: if the purpose of a resource is to perform an unsafe action, the resource owner MUST disable or disallow that action when it is accessed using a safe request method. The RFC gives page?do=delete as its own example. A GET that mutates makes CSRF through an <img> or <script src> tag trivial, because nothing is preflighted.

Defined

GET parameters land in server logs, browser history, Referer headers, and shared caches. §17.9 says plainly that URIs are intended to be shared, not secured, and that it is unwise to put anything sensitive in one. Hunt for tokens, session identifiers, and personal data riding in the query string.

Defined

GET responses are cacheable by default (§9.2.3), which is what turns a GET that reflects request data unsafely into an entry point for cache deception and cache poisoning.

Not what 9110 says

§9.2.1 also says the safe definition does not prevent an implementation from behaving in ways that are not entirely read-only, offering access logging and advertising charges as acceptable side effects. Safe describes what the client asked for and can be held accountable for. It is not a promise that the server sat still.

HEAD

§9.3.2

Identical to GET except that the server MUST NOT send content in the response.

Field

Cheap enumeration primitive: fire HEAD across a wordlist and read status codes without paying for response bodies. Faster fuzzing, with the same routing and authorization logic in a correctly built server.

SHOULD / MAY

The header-parity rule is weaker than most checklists assume. §9.3.2 says the server SHOULD send the same header fields it would have sent for GET, then explicitly permits a server to MAY omit fields whose values are determined only while generating content, naming Content-Length and Vary as the examples.

Field

Some frameworks route GET and HEAD through different code paths, so a HEAD-only authorization bypass is a real and recurring finding. Nothing in 9110 predicts this; it follows from how web frameworks dispatch verbs.

Not what 9110 says

The popular claim that Content-Length on a HEAD response leaks the true size of a body you are not allowed to GET is shakier than it sounds. §9.3.2 explicitly allows the server to omit Content-Length on HEAD. A present value is worth reading; an absent one proves nothing.

POST

§9.3.3

Submit content to be processed by the target resource: create, append, or trigger a process.

SHOULD / MAY

Not idempotent by definition (§9.2.2). The RFC aims its guidance at retries: a client SHOULD NOT automatically retry a non-idempotent request, and a proxy MUST NOT. Race-the-request tooling exploits servers built as though that guidance made repeats impossible rather than merely discouraged.

Defined

The classic CSRF target when same-site and token defences are absent. POST is unsafe under §9.2.1, and a simple form POST is not preflighted by browsers.

Field

Method confusion: re-send a POST endpoint as GET or PUT. Inconsistent method enforcement across a load balancer, a filter, and an application server is a common bypass chain, and is entirely an implementation property.

PUT

§9.3.4

Replace the target resource state with the enclosed representation.

Field

If exposed and unauthenticated, PUT is arbitrary file write. Try PUT of a script file, PUT over an existing static asset, and PUT with traversal in the target URI.

Defined

Idempotent per §9.2.2, but that property describes the intended effect of repeats. The RFC says outright that a server stays free to log, keep revision history, or otherwise produce non-idempotent side effects. Verify that the overwrite behaviour is not itself the exploit.

SHOULD / MAY

Partial PUT is defined, not undefined. §14.5 describes Content-Range on a PUT, notes that support is inconsistent and depends on private agreements with user agents, and says an origin server SHOULD respond 400 when it receives Content-Range on a PUT it does not support. Inconsistent handling of that case between proxy and origin is the interesting part.

Field

Test alongside DELETE and the WebDAV verbs. Misconfigured allow-lists routinely permit PUT while their operators believe only GET and POST are reachable.

Not what 9110 says

Security material frequently describes partial PUT as "undefined by the spec". RFC 9110 §14.5 defines it, warns that it is not backwards compatible with the original definition of PUT, and points at PATCH (RFC 5789) as the cleaner route.

DELETE

§9.3.5

Remove the association between the target resource and its current functionality.

Field

IDOR proving ground. A DELETE against a neighbouring identifier is the fastest way to demonstrate horizontal privilege escalation with unambiguous impact.

Defined

Idempotent per §9.2.2, so a second DELETE against an already-removed resource should have the same intended effect as the first. A server that instead throws and returns a verbose 500 is leaking implementation detail, which is a §17.12 disclosure concern rather than an idempotency violation.

Field

Check whether DELETE passes through the same authorization middleware as GET. Frameworks that wire authorization per verb sometimes only cover the verbs their developers exercised.

CONNECT

§9.3.6

Establish a tunnel to the server identified by the request target, commonly to carry TLS through a proxy.

SHOULD / MAY

The RFC names this risk itself: "There are significant risks in establishing a tunnel to arbitrary servers", with a CONNECT to port 25 turning the proxy into a spam relay as its worked example. Proxies that support CONNECT SHOULD restrict it to a limited set of known ports or a configurable list of safe request targets.

Field

A reverse proxy or application server that unexpectedly accepts CONNECT is a tunnel to internal hosts and a direct SSRF primitive. Cloud metadata addresses and private address ranges are the usual targets.

Field

HTTP/2 reuses CONNECT for extended CONNECT (RFC 8441, bootstrapping WebSockets). Pseudo-header handling on those endpoints has its own quirks, distinct from the HTTP/1.1 story and outside the scope of 9110.

OPTIONS

§9.3.7

Request information about the communication options available for the target resource.

MUST

The fastest method-enumeration primitive in the document, and it is mandatory. §10.2.1: an origin server MUST generate an Allow header field in a 405 response, and MAY do so in any other response. If OPTIONS is filtered at the edge, send a deliberately wrong verb and read Allow off the 405.

Field

CORS preflight is built on OPTIONS plus Access-Control-Request-Method. Origin reflection combined with credentialed requests is a direct account-takeover primitive. None of CORS is defined in 9110; it is a Fetch-standard layer sitting on top.

Field

Compare the Allow list per endpoint. An endpoint advertising PUT or DELETE whose authorization was never wired for them is exactly the bug the DELETE notes are hunting.

Not what 9110 says

Allow is advertisement, not enforcement. §10.2.1 says its purpose is "strictly to inform" the recipient, and that the actual set of allowed methods is defined by the origin server at the time of each request. A verb missing from Allow is not evidence that the verb is refused.

TRACE

§9.3.8

Request an application-level loop-back of the request message, reflected back as the content of a 200 response.

MUST

The RFC puts the burden on the client. §9.3.8 says a client MUST NOT generate fields in a TRACE request containing sensitive data, calling it foolish to send stored credentials or cookies in one, and the final recipient SHOULD exclude request fields likely to contain sensitive data when generating the response content.

Field

Cross-site tracing is why TRACE became a checklist item: reflecting a request through script could surface cookies and credentials that JavaScript cannot otherwise read. Browsers have blocked the verb from scripted requests for years, so treat an enabled TRACE as a hardening signal rather than a live exploit chain.

Defined

TRACE with Max-Forwards (§7.6.2) is a topology mapper the RFC endorses in as many words, calling it useful for testing a chain of proxies. Via values in the reflected message trace the request chain.

Not what 9110 says

TRACE being enabled is worth reporting, but the usual write-up overstates the mechanism. The RFC never says a server must refuse TRACE. It says clients must not put secrets in one and recipients should strip the sensitive fields. A server that reflects a TRACE is following §9.3.8, not breaking it.

PATCH

RFC 5789
Field

PATCH is not defined by RFC 9110 and is not one of its methods. 9110 mentions it once in a normative context: §14.5 points at a different method that has been specifically defined for partial updates, naming PATCH (RFC 5789), as the alternative to partial PUT. Everything interesting about PATCH from an offensive angle is therefore field knowledge rather than a reading of this document. Partial-update endpoints are mass-assignment magnets, so diff the fields a PATCH body is documented to touch against the fields the server actually accepts.

Not what 9110 says

Some references call PATCH the method registry canonical example of an extension method. §16.1 contains no such example; it is a heading over a pointer to the IANA method registry and nothing more.

Fields

33 fields, grouped by the job they do in a message. Each carries what the document defines it for, what an attacker does with it, and one probe that produces a signal. The tier on each attack note says whether you are citing a requirement or describing a habit.

Hostrequest§7.2

Carries the host and port from the target URI so that one server can distinguish resources across many host names.

Defined

The RFC flags this field itself. Because host and port act as an application-level routing mechanism, §7.2 calls Host "a frequent target for malware seeking to poison a shared cache or redirect a request to an unintended server", and singles out interception proxies that route or build cache keys from it without first verifying that the intercepted connection targets a valid address for that host. Duplicate Host lines, a trusted port suffix, and an internal name sent to the public address are the standard probes.

Probe

curl -H 'Host: evil.tld' https://target/ then repeat with duplicate Host headers and an absolute-form request-target to see which one wins.

:authority pseudo-headerrequest§7.2

HTTP/2 and HTTP/3 control data that supplants Host in some cases.

MUST

§7.2 requires a user agent to generate Host unless it sends that information as an :authority pseudo-header, but 9110 does not adjudicate what happens when a message carries both and they disagree. Translation layers between an h2 front end and an h1 back end have to invent an answer, and the answers they invent differ.

Probe

Send a request over h2 carrying both a Host header and a differing :authority, then observe which value the origin actually routes on.

Not what 9110 says

The precedence rule usually cited here lives in the version-specific documents, RFC 9113 for HTTP/2, not in 9110. All 9110 says is that Host is, in some cases, supplanted by :authority.

Viarequest and response§7.6.3

Records the chain of intermediaries a message passed through.

Defined

Free reconnaissance. Via exposes the proxy stack, often with software names and versions, which narrows a desync technique to the software combination actually sitting in front of the origin. §9.3.8 points at Via as the field of particular interest in a TRACE response for the same reason.

Probe

Log Via across the whole recon pass and build the proxy topology before choosing a technique.

Max-Forwardsrequest§7.6.2

Limits how many times a TRACE or OPTIONS request may be forwarded by intermediaries.

Defined

Decrementing Max-Forwards on a TRACE fingerprints how many hops sit between you and the origin, mapping internal topology from outside. The RFC describes this as a diagnostic; it works identically as reconnaissance.

Probe

Send TRACE with Max-Forwards 0, then 1, then 2, and diff which hop answers each time.

Content-Typerequest and response§8.3

Declares the media type of the representation so the recipient parses it correctly.

Field

Media-type confusion is the whole game. Send JSON to an endpoint expecting form encoding, or the reverse, to sidestep filters that only pattern-match one type. Charset parameters have historically enabled encoding-based filter bypasses on legacy parsers.

Probe

Fuzz the media type and the charset parameter independently of the body. Many frameworks trust the declared type over sniffing the content.

Content-Lengthrequest and response§8.6

Declares the octet length of the content, used for message framing.

MUST

The 9110 hook for smuggling is §5.4, and it is normative: a server that receives a field line, field value, or set of fields larger than it wishes to process MUST respond with an appropriate 4xx, because "Ignoring such header fields would increase the server's vulnerability to request smuggling attacks". Silently truncating instead of rejecting is a violation with a consequence the RFC names.

Probe

Framing itself is RFC 9112 territory. Start any smuggling engagement by checking whether the front end and back end agree on how Content-Length and Transfer-Encoding interact, then come back to §5.4 for oversized-field behaviour.

Not what 9110 says

CL.TE and TE.CL are not 9110 bugs. Transfer-Encoding is defined in RFC 9112 and the smuggling analysis lives in its §11.2. 9110 only points at it.

Content-Encodingrequest and response§8.4

Declares the codings applied on top of the media type.

Defined

This is the field behind §17.6, Attacks Using Shared-Dictionary Compression. Compressing attacker-influenced content alongside a secret in one response leaks the secret through response-size deltas, which is the BREACH and CRIME family.

Probe

Check whether reflected input and a secret share a compression context, and whether Vary separates them.

Content-Locationresponse§8.7

Names the specific URI belonging to the representation actually returned.

Field

Divergence between the requested URI and Content-Location can expose internal routing or rewrite rules and backend host names that are not otherwise visible.

Probe

Diff Content-Location across content-negotiated variants of the same resource.

ETagresponse§8.8.3

Opaque validator representing the current state of a selected representation.

Defined

§17.14 names an entity-tag abuse directly, and it is a privacy attack rather than an enumeration one. A site can construct a semantically invalid entity tag unique to a user, send it in a cacheable response with a long freshness time, and read it back from later conditional requests as a persistent identifier for as long as the user agent keeps the cache entry.

Probe

For the tracking case, look for entity tags that stay stable per client across genuinely different representations. For the enumeration case, compare how tags are derived across resources you can and cannot reach.

Not what 9110 says

The familiar claim that weak ETags leak inode numbers or file sizes describes one historical server implementation, not anything 9110 requires. §8.8.1 defines weak versus strong purely by whether the validator changes on every observable change to the representation data. It says nothing about predictability.

Last-Modifiedresponse§8.8.2

Timestamp of last modification, used as a validator.

Field

Passive intelligence on deployment cadence and on whether a resource is static or generated. Paired with If-Modified-Since it becomes a 200-versus-304 signal for confirming that a resource exists even when its content is withheld.

Probe

Probe with If-Modified-Since across a date range to infer when a hidden resource last changed.

If-Matchrequest§13.1.1

Makes the request conditional on the current validator matching, which is how HTTP expresses optimistic concurrency on writes.

Defined

§8.8.1 says strong validators are what make lost-update avoidance work. An application that never sends or never enforces If-Match on PUT and DELETE has no lost-update protection at all, so a concurrency race can be forced deliberately against a transfer or a balance update.

Probe

Fire concurrent writes without If-Match and check whether the server accepts a write built on stale state.

If-None-Matchrequest§13.1.2

Makes a request conditional on the validator not matching, the standard cache-revalidation precondition.

Field

A 200-versus-304 difference on a resource you should not be able to enumerate is a confirmation signal, particularly on endpoints whose access control lives at the rendering layer rather than the data layer.

Probe

Send a validator harvested from another account resource. A 304 suggests the validator scheme is not scoped per authorization.

If-Modified-Since and If-Unmodified-Sincerequest§13.1.3, §13.1.4

Time-based counterparts to the entity-tag preconditions.

Field

The same signal class as the entity-tag preconditions, but reachable even when the application never emits an ETag, because something in the stack usually supplies a Last-Modified.

Probe

Binary-search a date range to infer when a resource was created or updated.

If-Rangerequest§13.1.5

Makes a Range request conditional: if the validator is stale, the server returns the full representation instead of a partial one.

Defined

The degradation is the point. Where partial-content and full-content handling take different code paths with different access checks, a deliberately stale validator forces the full-response path.

Probe

Send an old validator in If-Range against a range-restricted endpoint and check whether it degrades to a full 200.

Rangerequest§14.2

Requests sub-ranges of the representation rather than the whole thing.

Defined

§17.15 is titled Denial-of-Service Attacks Using Range and states the asymmetry outright: the effort required to request many overlapping ranges of the same data is tiny compared with the time, memory, and bandwidth consumed serving them. The RFC adds that multipart range requests are not designed to support random access.

Probe

Compare latency for a normal range against a set of many small out-of-order ranges on a large resource, at single-request scale. This is a named, citable risk, so a measurement is enough for a report.

Not what 9110 says

Ought to is the word the RFC uses. §17.15 says servers ought to ignore, coalesce, or reject egregious range requests, and carries no MUST or SHOULD, so a server that happily serves a pathological range set is not violating 9110. It is declining advice.

Accept-Rangesresponse§14.3

Advertises whether the server supports range requests for this resource.

Defined

Tells you whether the §17.15 surface exists on a given endpoint before you spend time on it.

Probe

Send HEAD first and read Accept-Ranges.

Content-Rangeresponse§14.4

Describes which sub-range a partial response carries, and the total length of the representation.

Defined

The complete-length field discloses the true size of a representation even when you are only permitted a single byte of it, which is enough to confirm that a file exists and how large it is.

Probe

Request the first byte and read the total from the Content-Range value.

Acceptrequest§12.5.1

The preferred media types for the response, with optional quality values.

Field

Framework-level negotiation has repeatedly shipped format-confusion bugs, where asking for a format the documented API never advertises reaches a different and less hardened parser. Undocumented negotiated formats are unauthenticated attack surface.

Probe

Cycle Accept through XML, YAML, and legacy formats even against an API documented as JSON-only.

Accept-Encodingrequest§12.5.3

The content codings the client will accept.

Defined

Controls whether the §17.6 compression side channel can be triggered at all, which makes forcing or withholding compression a prerequisite step rather than the attack itself.

Probe

Toggle between identity and a compressing coding on responses that carry both a secret and reflected input.

Accept-Languagerequest§12.5.4

The preferred natural languages for the response.

Defined

§17.13 singles this field out beyond fingerprinting: the RFC observes that understanding a given language set might be strongly correlated to membership in a particular ethnic group, and suggests user agents omit it except for sites the user has permitted. Separately, localisation pipelines that build a template or file path out of the value have shipped traversal bugs.

Probe

Fuzz the value with traversal and injection payloads, not only with locale codes, against any application with visibly localised content.

Varyresponse§12.5.5

Names the request fields that influenced content selection, so that caches can key correctly.

SHOULD / MAY

A missing or incomplete Vary is the usual root cause of cache poisoning: when a response depends on an input the cache does not key on, one poisoned entry serves every later visitor. §12.5.5 gives caches a MUST NOT that depends on Vary, and gives origin servers only a SHOULD to generate it.

Probe

Identify unkeyed inputs that change the response, then check whether Vary lists them.

Not what 9110 says

The RFC hands the origin server an explicit escape: Vary might be elided when an origin server considers variance in content selection to be less significant than the performance impact on caching. A missing Vary is a strong finding operationally and a weak one as a conformance claim.

WWW-Authenticateresponse§11.6.1

The challenge sent with a 401, naming the schemes and the realm the server accepts.

Field

Realm strings and scheme lists are reconnaissance. They usually reveal which authentication backend is in play, and the realm value sometimes carries an internal host name.

Probe

Capture the field verbatim on every 401. It decides which bypass family is even applicable.

Authorizationrequest§11.6.2

Carries credentials for the challenged scheme.

Defined

§17.16.1 states that HTTP defines no single mechanism for keeping credentials confidential, that the framework is inadequate for existing schemes providing no confidentiality of their own, and that services depending on individual user authentication require a secured connection before credentials are exchanged. The practical test is whether the field survives a redirect to a different origin.

Probe

Build a redirect chain ending on a host you control and confirm whether Authorization survives the cross-origin hop.

Not what 9110 says

9110 does not say what a client must do with Authorization across a redirect. That rule lives in the Fetch standard and in each client implementation, which is exactly why they disagree.

Proxy-Authenticate and Proxy-Authorizationresponse and request§11.7

The same challenge and credential pattern, scoped to a proxy rather than to the origin.

Defined

Confusing proxy-scoped credentials with origin-scoped credentials is a real disclosure class. A Proxy-Authorization value forwarded past the proxy to the origin, or the reverse, hands credentials to a party that was never meant to see them.

Probe

In any chain with a forward or authenticating proxy, verify which hop actually consumes which field.

Authentication-Inforesponse§11.6.3

Carries additional information after authentication has succeeded, alongside a 2xx.

Field

Scanners often miss it because it only appears on success, which makes its presence or absence a cheap way to tell a genuinely authenticated request from one that was merely syntactically accepted.

Probe

Log this field during credential testing to separate valid-but-blocked from simply wrong.

Refererrequest§10.1.3

Names the resource from which the target URI was obtained.

MUST

§10.1.3 requires a user agent to leave out the fragment and userinfo components, and nothing more. Everything else in the URI, query string included, travels to whatever third-party resource the page loads. §17.9 connects the two, noting that the field can reveal the immediate browsing history of the user and any personal information in the referring URI.

Probe

Grep a traffic capture for tokens in query strings, then check whether any outbound third-party request carries the same value in Referer.

User-Agentrequest§10.1.5

Identifies the client software making the request.

Defined

§17.13 says the field might contain enough information to uniquely identify a specific device when combined with other characteristics, particularly where the agent volunteers excessive detail about the system or its extensions. Offensively, the more interesting case is a backend that makes authorization or feature-flag decisions on the string, which is a soft access-control bypass.

Probe

Diff application behaviour, not just filter behaviour, across a set of agent strings, looking for internal-tooling or legacy-client code paths.

Not what 9110 says

Header order and casing are widely described as part of a §17.13 fingerprint. They are a real fingerprint, but they are not in §17.13, which discusses field content and names From, User-Agent, Cookie, and the proactive negotiation fields. §5.3 in fact says the order of fields with differing names is not significant.

Expectrequest§10.1.1

Signals that the client wants an interim 100 response before sending a large body.

Field

Divergent handling of 100-continue between a front-end proxy and a back-end origin is a known desync amplifier, because one hop may buffer the whole body while the other waits for an interim response.

Probe

Send Expect with a slow or oversized body across the proxy chain and watch for timing or state differences between hops.

Fromrequest§10.1.2

An email address for the human controlling the user agent, in practice used by well-behaved crawlers.

Defined

Rarely an attack vector. Worth knowing because §17.13 calls From the most obvious fingerprinting field in HTTP, which makes a populated From on inbound traffic a useful attribution signal when you are on the defending side.

Probe

No offensive test. Treat it as hygiene and attribution.

Locationresponse§10.2.2

Identifies a URI for redirection on a 3xx, or the newly created resource on a 201.

Field

A server-side fetcher that follows redirects turns an open redirect into full SSRF, defeating allow-list checks that only validate the first hop. 9110 defines what Location means and says nothing about whether a fetcher should follow it, which is why every URL-consuming feature answers differently.

Probe

Host a redirect chain and feed its first URL to any server-side fetching feature: webhooks, document generators, link unfurlers, image proxies.

Allowresponse§10.2.1

Lists the methods advertised as supported by the target resource.

MUST

Mandatory on a 405 and permitted anywhere else, which makes method enumeration free even when OPTIONS is filtered at the edge. A proxy MUST NOT modify the field, so what you receive is what the origin generated.

Probe

Trigger a 405 with an obviously wrong verb. Allow is usually still returned.

Not what 9110 says

See the OPTIONS note. Allow informs; it does not enforce.

Retry-Afterresponse§10.2.3

Indicates how long to wait before retrying, sent with a 503 or a 3xx.

Field

On rate-limit responses, the precision of the value can leak queue internals, and inconsistent values across endpoints help map which services share a limiter.

Probe

Compare Retry-After behaviour across endpoints to infer shared versus isolated rate limiting before choosing a pace.

Serverresponse§10.2.4

Identifies the software handling the request at the origin.

Defined

§17.12, Disclosure of Product Information, is the framing the RFC itself uses: a version string is a direct path to a vulnerability database. The first field worth logging in any reconnaissance pass.

Probe

Cross-reference Server and any framework-specific equivalents against public advisories before touching anything else.

Status codes

Status codes are the fastest signal in the protocol, because the difference between what a code is defined to mean in §15 and what an implementation does with it is visible from outside with a single request. Two of them, 403 and 404, are where the document explicitly hands the server a choice about how much existence to disclose.

1xx informational

2xx success

3xx redirection

4xx client error

5xx server error

100 Continue

§15.2.1Field

An interim response before a large body. Divergent handling of 100-continue between hops is a documented desync amplifier, so test it alongside Expect.

101 Switching Protocols

§15.2.2Field

Used for the Upgrade handshake. Confirm the upgrade target is authorized; protocol-switch endpoints sometimes bypass the middleware that wraps ordinary routes.

200 OK

§15.3.1Field

Baseline. Diff bodies and timings across privilege levels to find authorization leaks: fields present but unrendered, verbose errors for one role and terse ones for another.

201 Created

§15.3.2Field

The Location value on a 201 exposes the identifier scheme for new resources. Sequential identifiers here are a map for the IDOR sweep.

204 No Content

§15.3.5Field

Common on a successful DELETE or PUT. A 204 for a resource you do not own, rather than a 403 or 404, confirms an IDOR without needing to see a body.

206 Partial Content

§15.3.7Defined

Confirms range requests are honoured, which is the prerequisite check before measuring the §17.15 surface.

300 Multiple Choices

§15.4.1Field

Rarely implemented. Where it appears, check whether the choice list exposes representation URIs that are not linked anywhere else.

301 Moved Permanently

§15.4.2Field

Cached by clients and intermediaries, so a poisoned 301 has a long blast radius. Also the usual building block for redirect chains feeding SSRF.

302 Found

§15.4.3Defined

Historically ambiguous about method preservation. §15.4.3 acknowledges that user agents rewrite POST to GET here, contrary to the original intent, which is why clients within one stack can disagree about what a 302 means.

303 See Other

§15.4.4Defined

Means retrieve the new URI with GET regardless of the original method. Behaviour that deviates from that is a logic-bug signal.

304 Not Modified

§15.4.5Field

The response that turns conditional requests into an existence signal, as described throughout the conditional-request fields.

307 Temporary Redirect

§15.4.8MUST

§15.4.8 says the user agent MUST NOT change the request method if it performs an automatic redirection, which is exactly what distinguishes it from 302 in practice. Whether credentials survive the hop is a separate question 9110 does not answer.

308 Permanent Redirect

§15.4.9MUST

The same method preservation as 307, but cacheable long term, so the same credential test carries more persistence if the value is ever poisoned into a shared cache.

400 Bad Request

§15.5.1Field

Baseline malformed-request response. Verbose 400 bodies are a frequent stack-trace and framework leak, which §17.12 treats as a disclosure risk.

401 Unauthorized

§15.5.2Defined

Authentication is missing or invalid. Inconsistent 401-versus-403 use across one logical boundary is itself a map of the access-control model.

403 Forbidden

§15.5.4SHOULD / MAY

The server understood the request and refuses it. §15.5.4 is where the hide-behind-404 permission actually lives: an origin server that wishes to hide the current existence of a forbidden target resource MAY instead respond with a 404. It also says the client SHOULD NOT automatically repeat the request with the same credentials.

404 Not Found

§15.5.5Defined

§15.5.5 defines 404 as the origin server having found no current representation or being unwilling to disclose that one exists, which is what makes the substitution permitted by §15.5.4 legitimate. An application that returns 403 where it could have returned 404 is disclosing existence by choice.

405 Method Not Allowed

§15.5.6MUST

Delivers Allow for free, and §10.2.1 makes that mandatory. Trigger one deliberately when OPTIONS is filtered.

406 Not Acceptable

§15.5.7Field

The server cannot satisfy the negotiation constraints, which tells you which formats the parser will actually attempt.

409 Conflict

§15.5.10Field

Signals a state conflict, which is useful for confirming that a race window exists at all rather than the application silently taking the last write.

411 Length Required

§15.5.12Field

The server refuses a request without Content-Length, which matters when probing how chunked and length-delimited framing are handled.

413 Content Too Large

§15.5.14Defined

The size-limit enforcement point. Read it with §17.5 on protocol element length: HTTP sets no predefined limits, so implementations must defend themselves, and they do so inconsistently.

414 URI Too Long

§15.5.15Defined

Confirms a request-target ceiling. §15.5.15 itself notes that the condition sometimes results from a client improperly converting a POST to a GET with long query information, and sometimes from an attack.

415 Unsupported Media Type

§15.5.16Field

Maps the declared boundaries of the parser, which narrows the Content-Type values worth fuzzing further.

416 Range Not Satisfiable

§15.5.17Defined

Boundary-testing this reveals the true representation length even where the content is withheld, the same intelligence Content-Range gives.

421 Misdirected Request

§15.5.20Defined

Exists precisely for the connection-reuse confusion described in §4.3.3. An origin sends 421 to reject a target URI that does not match an origin it has been configured for, or does not match the connection context the request arrived on. A server that answers instead of rejecting is the connection-confusion bug class.

429 Too Many Requests

RFC 6585Field

Not defined in 9110. Universally deployed anyway, and its threshold behaviour shapes any rate-limit strategy.

500 Internal Server Error

§15.6.1Field

Generic catch-all. Verbose 500 bodies carrying stack traces, query fragments, or file paths remain one of the highest-signal free intelligence sources in an assessment.

502 Bad Gateway

§15.6.3Defined

Confirms a gateway sits in front of an unreachable origin, which helps map the intermediary chain before choosing a technique.

503 Service Unavailable

§15.6.4Field

Distinguish genuine overload from a deliberate soft block by diffing Retry-After presence and response timing.

504 Gateway Timeout

§15.6.5Field

A slow-path timing signal. Differential timeouts across parameters can reveal blind injection or SSRF with no reflected output.

Authority

Origin is defined in §4.3.1 as the triple of scheme, host, and port, normalised. Two origins differ if any one of the three differs, port included. That single definition underpins same-origin policy, CORS, and cookie scoping, which is why a surprising number of cross-origin bugs turn out to be origin-comparison bugs.

§4.3.3 · port confusion

The RFC works this example itself. Where a host runs distinct services on different ports, it says checking the target URI at the origin server is necessary even after the connection has been secured, because a network attacker might cause connections for one port to be received at another. Failing to check lets the attacker substitute a response from the other port and have it look authoritative.

Defined
§4.3.3 · connection reuse

Over HTTP/2 and HTTP/3 a client attributes authority to a server for any host in the certificate, provided it believes it could open a connection to that host, which in practice means a DNS check that the name resolves to the same address. An origin that answers for a name it does not serve, instead of sending 421, is the connection-confusion bug class.

Defined
§4.2.4 · deprecated userinfo

A sender MUST NOT generate the userinfo subcomponent in an http or https URI within a message. On receipt from an untrusted source a recipient SHOULD parse for it and treat its presence as an error, because, in the words of the RFC, it is likely being used to obscure the authority for the sake of phishing attacks.

MUST

401 against 403

401 Unauthorized

Authentication is missing or will not do. The challenge in WWW-Authenticate (§11.6.1) names the scheme and realm, which tells you which bypass family is even applicable. Consistent 401s across an unauthenticated sweep mean a clean authentication boundary worth mapping before testing anything.

403 Forbidden

The server understood the request and refuses anyway, so this is the authorization boundary rather than the authentication one. §15.5.4 permits an origin server to answer 404 instead when it wants to hide that a forbidden resource exists. An application that returns 403 where it could have returned 404 has chosen to disclose existence.

Authentication fields (§11)

WWW-Authenticate§11.6.1

The challenge sent with a 401, naming the schemes and the realm the server accepts.

Field

Realm strings and scheme lists are reconnaissance. They usually reveal which authentication backend is in play, and the realm value sometimes carries an internal host name.

Authorization§11.6.2

Carries credentials for the challenged scheme.

Defined

§17.16.1 states that HTTP defines no single mechanism for keeping credentials confidential, that the framework is inadequate for existing schemes providing no confidentiality of their own, and that services depending on individual user authentication require a secured connection before credentials are exchanged. The practical test is whether the field survives a redirect to a different origin.

Not what 9110 says

9110 does not say what a client must do with Authorization across a redirect. That rule lives in the Fetch standard and in each client implementation, which is exactly why they disagree.

Proxy-Authenticate and Proxy-Authorization§11.7

The same challenge and credential pattern, scoped to a proxy rather than to the origin.

Defined

Confusing proxy-scoped credentials with origin-scoped credentials is a real disclosure class. A Proxy-Authorization value forwarded past the proxy to the origin, or the reverse, hands credentials to a party that was never meant to see them.

Authentication-Info§11.6.3

Carries additional information after authentication has succeeded, alongside a 2xx.

Field

Scanners often miss it because it only appears on success, which makes its presence or absence a cheap way to tell a genuinely authenticated request from one that was merely syntactically accepted.

Caching and conditional

9110 defines the semantics of caching, the validators and the preconditions, while the storage and freshness rules live in RFC 9111. The exploitation surface starts here, because validators (ETag, Last-Modified) and preconditions (If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since, If-Range) are what a cache, or your race-condition tooling, keys on. These 7 fields also appear under Fields; they are collected here because they are one subject.

If-Match§13.1.1

Makes the request conditional on the current validator matching, which is how HTTP expresses optimistic concurrency on writes.

Defined

§8.8.1 says strong validators are what make lost-update avoidance work. An application that never sends or never enforces If-Match on PUT and DELETE has no lost-update protection at all, so a concurrency race can be forced deliberately against a transfer or a balance update.

Probe

Fire concurrent writes without If-Match and check whether the server accepts a write built on stale state.

If-None-Match§13.1.2

Makes a request conditional on the validator not matching, the standard cache-revalidation precondition.

Field

A 200-versus-304 difference on a resource you should not be able to enumerate is a confirmation signal, particularly on endpoints whose access control lives at the rendering layer rather than the data layer.

Probe

Send a validator harvested from another account resource. A 304 suggests the validator scheme is not scoped per authorization.

If-Modified-Since and If-Unmodified-Since§13.1.3, §13.1.4

Time-based counterparts to the entity-tag preconditions.

Field

The same signal class as the entity-tag preconditions, but reachable even when the application never emits an ETag, because something in the stack usually supplies a Last-Modified.

Probe

Binary-search a date range to infer when a resource was created or updated.

If-Range§13.1.5

Makes a Range request conditional: if the validator is stale, the server returns the full representation instead of a partial one.

Defined

The degradation is the point. Where partial-content and full-content handling take different code paths with different access checks, a deliberately stale validator forces the full-response path.

Probe

Send an old validator in If-Range against a range-restricted endpoint and check whether it degrades to a full 200.

Range§14.2

Requests sub-ranges of the representation rather than the whole thing.

Defined

§17.15 is titled Denial-of-Service Attacks Using Range and states the asymmetry outright: the effort required to request many overlapping ranges of the same data is tiny compared with the time, memory, and bandwidth consumed serving them. The RFC adds that multipart range requests are not designed to support random access.

Probe

Compare latency for a normal range against a set of many small out-of-order ranges on a large resource, at single-request scale. This is a named, citable risk, so a measurement is enough for a report.

Not what 9110 says

Ought to is the word the RFC uses. §17.15 says servers ought to ignore, coalesce, or reject egregious range requests, and carries no MUST or SHOULD, so a server that happily serves a pathological range set is not violating 9110. It is declining advice.

Accept-Ranges§14.3

Advertises whether the server supports range requests for this resource.

Defined

Tells you whether the §17.15 surface exists on a given endpoint before you spend time on it.

Probe

Send HEAD first and read Accept-Ranges.

Content-Range§14.4

Describes which sub-range a partial response carries, and the total length of the representation.

Defined

The complete-length field discloses the true size of a representation even when you are only permitted a single byte of it, which is enough to confirm that a file exists and how large it is.

Probe

Request the first byte and read the total from the Content-Range value.

§17.15 · Denial-of-Service Attacks Using RangeDefined

Pathological Range headers requesting many small overlapping byte ranges force a server to build a multipart/byteranges response (§14.6), doing seek and copy work per range. The RFC states the asymmetry itself: the effort to request them is tiny next to the time, memory, and bandwidth consumed serving them, and multipart range requests were never designed to support random access. Cite the section directly, since it is an acknowledged risk rather than a novel technique.

The remedy is phrased as advice. Servers ought to ignore, coalesce, or reject egregious requests, singling out more than two overlapping ranges or many small ranges in one set. There is no MUST or SHOULD in §17.15, so a server that serves a pathological range set is declining advice, not violating the specification.

Section 17

Section 17 is the threat model the authors wrote for their own protocol, and it is unusual for a specification to name its attack classes this directly. Sixteen subsections, reproduced here as headings with the mechanism described in this page's own words. Three of them are routinely cited for claims they do not make, and those are marked.

For an http URI, authority rests on the local name resolution service, so any attack on the host table, cached names, or resolver libraries becomes an avenue for attack on authority. Once an address is obtained, IP routing is the next exposure. The https scheme is intended to prevent or at least reveal many of these, provided the client properly verifies that the server identity matches the target URI authority, and the RFC concedes that correctly implementing such verification can be difficult.

Play

Test Host and :authority mismatches, and on h2 or h3 targets test connection reuse across a certificate covering several origins, then check 421 handling as described in §4.3.3.

Not what 9110 says

The line often quoted here, that http provides a very weak sense of authority, is not in §17.1. The section makes the same point at length without that phrasing, so cite the mechanism rather than the epigram.

Any proxy, gateway, or interception proxy in the chain can rewrite, misroute, or drop parts of a message.

Play

Map every intermediary through Via, Server, and timing fingerprints, then target the desync class known for that specific proxy and origin combination.

Resource-identifying strings are frequently handed to a filesystem or a shell without full normalisation.

Play

Traversal, null-byte, and mixed-encoding fuzzing on every path segment, including inside PUT targets and filenames derived from Content-Disposition, not only the URL path.

Any field value used to build a downstream command, template, or query is an injection point, not only the obvious ones.

Play

Do not stop at the body. Header values, the request-target itself, and field names have all reached logs, queries, and templates unsanitised in shipped products.

HTTP places no predefined limit on field line, field value, or section length, so implementations have to defend themselves, and §5.4 makes rejecting oversized fields a MUST rather than an option.

Play

Oversized headers, large cookie jars, long request-targets, and many repeated fields, run as a differential test to find which layer actually enforces a limit.

Compressing a secret together with attacker-controlled data leaks the secret through response-size differences.

Play

This is the BREACH and CRIME family. Look for tokens, session identifiers, or keys sharing a compressed response with any reflected input.

HTTP messages are chatty by design, and user agent, Referer, cookies, and content routinely carry more than the application author intended.

Play

Run a passive collection pass over full traffic and grep for personal data and secrets outside the obvious response body. Headers and URIs are the usual sites.

Everything an origin logs, including the full URI with its query string, becomes a liability if the log store is reachable.

Play

Any access to logs or observability during an engagement puts full query strings, and any tokens embedded in them, into scope.

URIs are intended to be shared, not secured, even when they identify secure resources. They appear on displays, in printed pages, and in unprotected bookmark lists, and are logged or displayed by servers, proxies, and user agents alike. The section also connects Referer to the immediate browsing history of the user.

Play

Flag every token-in-URL design and test it for Referer leakage to third-party resources loaded on the same page.

Case-insensitive matching and duplicate-field handling are implemented inconsistently across stacks.

Play

Field-name case fuzzing and duplicate-field probing, which is a direct enabler for smuggling and filter bypass.

Fragments are never sent to the server, so client-side redirect logic that leaks them cross-origin is a distinct class from server-side redirect leaks.

Play

Test client-side redirect handlers, not just 3xx responses, for fragment leakage to a different origin. Common in single-page implicit-flow implementations.

Product and version strings in Server, User-Agent, and their equivalents are a direct path from fingerprint to advisory.

Play

First move in reconnaissance. Cross-reference every version string surfaced anywhere, including error pages and build artefacts, against public advisories.

A set of techniques for identifying a specific user agent over time through its unique set of characteristics. The section names From as the most obvious field, User-Agent where the agent sends excessive system detail, and, as the source of unique information least expected by users, the proactive negotiation fields: Accept, Accept-Charset, Accept-Encoding, and Accept-Language.

Play

When evading fingerprint-based detection, matching the negotiation fields matters at least as much as the agent string.

Not what 9110 says

§17.13 is about the content of fields, not their order or casing. Header ordering and transport-level fingerprints are real and widely used, but they are outside this document, and §5.3 states that the order of fields with differing names is not significant.

The subject here is privacy, not integrity. The section says validators are not intended to ensure the validity of a representation or guard against malicious changes, then describes the abuse it actually cares about: a site can deliberately construct a semantically invalid entity tag unique to a user or user agent, send it in a cacheable response with a long freshness time, and read that tag in later conditional requests as a means of re-identifying that user for as long as the cache entry is retained.

Play

Look for entity tags that stay constant per client across representations that genuinely differ. On the defending side, this is why clearing the cache has to accompany other privacy actions.

Not what 9110 says

This section is regularly cited for the claim that weak or sequential validators reveal deployment cadence and internal counters. It says nothing of the kind. That inference is field practice; §17.14 is about entity tags used as tracking identifiers.

The document names its own denial-of-service class here. The effort required to request many overlapping ranges of the same data is tiny compared with the time, memory, and bandwidth consumed serving them, and multipart range requests were never designed to support random access.

Play

An easy, citable finding precisely because the document names it. The remedy the RFC offers is that servers ought to ignore, coalesce, or reject egregious range requests, singling out requests for more than two overlapping ranges or for many small ranges in a single set.

Not what 9110 says

Stated as advice rather than as a requirement. §17.15 uses ought to, with no MUST or SHOULD anywhere in it, so a server that serves a pathological range set is not violating the specification.

Four sub-risks: confidentiality of credentials (§17.16.1), credentials and idle clients (§17.16.2), protection spaces (§17.16.3), and additional response fields (§17.16.4). The first is load-bearing: the framework defines no single mechanism for maintaining the confidentiality of credentials and is inadequate for existing schemes that provide none of their own, so services depending on individual user authentication require a secured connection before credentials are exchanged.

Play

Test credential replay across an idle timeout, test whether a protection-space boundary is enforced server-side rather than merely cached by the client, and treat every value in an authentication response field as untrusted input.

Probes

Scope

Everything below assumes written authorization to test the target. These are single-request reconnaissance probes chosen to produce a citable signal, not exploit payloads, and the range and oversized-field entries in particular touch behaviour that §17.15 and §17.5 describe as denial-of-service surface. Confirm scope before running any of them, and do not scale them up on a system you do not own.

Ten probes, one per concept in this reading. Each is meant to fire a fast yes-or-no signal that maps back to a section you can cite, after which real tooling takes over. Replace target throughout.

Method surface mapping
for m in GET HEAD POST PUT DELETE OPTIONS TRACE PATCH; do
  printf '%-9s' "$m"
  curl -s -o /dev/null -w '%{http_code}\n' -X "$m" https://target/path
done
Allow enumeration, through OPTIONS and through a 405
curl -s -i -X OPTIONS https://target/api/resource | grep -i '^allow:'
curl -s -i -X BOGUSVERB https://target/api/resource | grep -i '^allow:'
TRACE reflection probe, raw because browsers block the verb
curl -s -i -X TRACE -H 'X-Probe: reflect-me' https://target/ | grep -i 'x-probe'
Host confusion
curl -s -i https://target/ -H 'Host: internal-admin.target.local'
Range surface check, one request, no flood
curl -s -i https://target/largefile -H 'Range: bytes=0-0' \
  | grep -i 'content-range\|accept-ranges'
Conditional-request existence signal
curl -s -o /dev/null -w '%{http_code}\n' https://target/resource \
  -H 'If-None-Match: "guessed-validator"'
Open redirect into a server-side fetcher
# your-redirector/step1 answers 302 to the internal address under test
curl -s -i 'https://target/fetch?url=https://your-redirector/step1'
Redirect credential retention, 307 preserves the method
curl -s -i -X POST https://target/redirects-cross-origin \
  -H 'Authorization: Bearer TESTTOKEN' -d 'x=1' -L -v 2>&1 \
  | grep -i 'authorization\|> POST\|> GET'
Vary coverage against an unkeyed input
curl -s -i https://target/ -H 'X-Forwarded-Host: evil.tld' | grep -i 'vary\|cache'
Oversized field handling, per 5.4 and 17.5
python3 -c "import sys; sys.stdout.write('GET / HTTP/1.1\r\nHost: target\r\n' + 'X-Pad: A\r\n'*2000 + '\r\n')" \
  | nc target 80 | head -1

References

RFC 9110 is the anchor: every bare section number on this page points into it. The rest are the neighbouring documents this reading has to hand work off to, because several of the attack classes people file under 9110 are defined elsewhere.

  1. RFC 9110

    Fielding, R., Nottingham, M., and J. Reschke, Eds., HTTP Semantics, STD 97, RFC 9110, June 2022. The anchor document. Every section reference on this page points here.

    https://datatracker.ietf.org/doc/html/rfc9110
  2. RFC 9112

    Fielding, R., Nottingham, M., and J. Reschke, Eds., HTTP/1.1, STD 99, RFC 9112, June 2022. Message syntax and framing. Request smuggling is analysed in its §11.2, which is what 9110 §5.4 points at.

    https://datatracker.ietf.org/doc/html/rfc9112
  3. RFC 9111

    Fielding, R., Nottingham, M., and J. Reschke, Eds., HTTP Caching, STD 98, RFC 9111, June 2022. Storage and freshness rules. 9110 defines the validators and preconditions a cache keys on; 9111 defines what the cache does with them.

    https://datatracker.ietf.org/doc/html/rfc9111
  4. RFC 5789

    Dusseault, L. and J. Snell, PATCH Method for HTTP, RFC 5789, March 2010. Where PATCH is actually defined, referenced by 9110 §14.5.

    https://datatracker.ietf.org/doc/html/rfc5789
  5. RFC 9113

    Thomson, M. and C. Benfield, Eds., HTTP/2, RFC 9113, June 2022. Defines the :authority pseudo-header and its precedence over Host, which 9110 mentions but does not adjudicate.

    https://datatracker.ietf.org/doc/html/rfc9113
  6. RFC 8441

    McManus, P., Bootstrapping WebSockets with HTTP/2, RFC 8441, September 2018. The extended CONNECT referenced in the CONNECT notes.

    https://datatracker.ietf.org/doc/html/rfc8441

Scope, and what the tiers do not cover. Section numbers were checked against the RFC 9110 text of June 2022; where this page quotes the document the fragment is short and marked, and everything else is written in its own words. The tiers describe this document only. A claim tiered Field may still be well established elsewhere, and several attack classes commonly filed under 9110 are actually defined in its neighbours: message framing and smuggling in RFC 9112, storage and freshness in RFC 9111, pseudo-header precedence in RFC 9113, CORS in the Fetch standard. Nothing here is a vulnerability disclosure or a claim about any particular product, and the probes assume a target you are authorized to test.