
Go CLI that inventories HTTPS endpoints negotiating HTTP/2 via ALPN to identify systems requiring CVE-2023-44487 mitigation review. Non-exploitative, certificate-verified TLS checks with safe defaults.
rapid-reset-check is a small Go CLI for quickly inventorying HTTPS endpoints that expose HTTP/2 and therefore need a CVE-2023-44487 mitigation review.
The scanner is deliberately non-exploitative. It resolves each target, opens a certificate-verified TLS connection, offers h2 and http/1.1 through ALPN, records what the peer selects, and closes the connection. It sends no HTTP request, HTTP/2 connection preface, stream, RST_STREAM frame, or flood traffic.
[!IMPORTANT] Negotiating
h2is an exposure observation, not proof that a service is vulnerable or unpatched. A remote handshake cannot verify an HTTP/2 implementation's Rapid Reset limits, patch level, upstream origin, or DDoS controls.
CVE-2023-44487 is a denial-of-service technique that abuses rapid HTTP/2 stream creation and cancellation. Attempting to prove the condition against a live service would itself require potentially disruptive traffic. This tool instead answers the safe first question: which tested TLS endpoints currently negotiate HTTP/2 and therefore require an operator to verify mitigation?
HTTP/2 over TLS is advertised using the h2 ALPN identifier defined by RFC 9113. Google recommends verifying or patching every HTTP/2-capable server, proxy, and load balancer in the request path; see its CVE-2023-44487 guidance.
Go is not required to run the tool. Download the archive for your platform from the latest GitHub release:
| Platform | Release asset |
|---|---|
| Linux x86-64 | rapid-reset-check_<version>_linux_amd64.tar.gz |
| Linux ARM64 | rapid-reset-check_<version>_linux_arm64.tar.gz |
| macOS Intel | rapid-reset-check_<version>_darwin_amd64.tar.gz |
| macOS Apple silicon | rapid-reset-check_<version>_darwin_arm64.tar.gz |
| Windows x86-64 | rapid-reset-check_<version>_windows_amd64.zip |
| Windows ARM64 | rapid-reset-check_<version>_windows_arm64.zip |
Extract the archive, then run rapid-reset-check --version. On Windows, the executable is named rapid-reset-check.exe.
Each release includes SHA256SUMS. On Linux, verify a downloaded archive from the same directory with:
sha256sum --ignore-missing --check SHA256SUMS
On macOS, compare shasum -a 256 <archive> with the matching line in SHA256SUMS. Published public-release archives also receive a GitHub artifact attestation, which can be checked with the GitHub CLI:
gh attestation verify <archive> --repo ramonzx6/http-script-json
No Node.js, cURL, nghttp2, or WHOIS installation is required.
go test ./...
go build -o rapid-reset-check ./cmd/rapid-reset-check
Source builds report dev from --version; release builds receive their version from the release tag.
Only scan endpoints you own or are authorized to assess.
Scan one or more public endpoints:
./rapid-reset-check example.com api.example.com:8443
Bare hostnames are normalized to HTTPS on port 443. Authority-only HTTPS URLs are also accepted:
./rapid-reset-check https://example.com https://api.example.com:8443
Scan the repository's JSON target list:
./rapid-reset-check --input json/urls.json
Use standard input for automation:
printf '["example.com", "api.example.com"]' | ./rapid-reset-check --input -
Run ./rapid-reset-check --help for all limits and output options.
--input accepts the original JSON array format:
[
"example.com",
"api.example.com:8443",
"https://www.example.net"
]
The object forms {"urls": [...]} and {"targets": [...]} are also supported. Positional targets and --input are intentionally mutually exclusive. Duplicate normalized endpoints are scanned once, and each run is limited to 4,096 input targets.
Only HTTPS endpoints are in scope. Credentials, non-root paths, queries, fragments, unsupported schemes, malformed ports, and ambiguous hostnames are rejected instead of silently rewritten.
| Assessment | Meaning |
|---|---|
h2_observed_review_required | At least one verified TLS peer selected h2. Review every HTTP/2 component in that path; this is not a vulnerability verdict. |
h2_not_observed_on_tested_path | Every selected address completed a verified handshake without selecting h2. This is a point-in-time path observation, not a safety guarantee. |
indeterminate | A DNS, connection, timeout, TLS, certificate, or address-limit issue prevented a complete observation. |
not_scanned_policy | The resolved addresses were excluded by the scanner's network safety policy. |
invalid_target | The input was malformed or outside the supported HTTPS authority scope. |
The report includes each resolved address attempted, negotiated ALPN, TLS version and cipher, limited certificate identity/validity data, timing, policy decisions, omitted-address counts, an explicit completeness flag, and a summary. It does not collect response bodies, response headers, cookies, or raw certificates.
--ca-file to add a private CA; there is no insecure verification mode.--allow-private only for internal endpoints you are authorized to assess.Example options:
./rapid-reset-check \
--format json \
--timeout 5s \
--concurrency 4 \
--max-addresses 8 \
example.com > report.json
For an authorized private-PKI endpoint:
./rapid-reset-check \
--allow-private \
--ca-file ./internal-root-ca.pem \
service.internal:8443
Exit code 0 means every target produced a complete ALPN observation. Exit code 1 means at least one target was invalid, blocked by policy, or indeterminate; the report is still written. CLI usage and configuration errors return 2. Observing h2 does not by itself change the exit code because it is an inventory signal, not a vulnerability verdict.
For every h2_observed_review_required result:
Results are specific to the hostname, DNS answers, network path, TLS endpoint, and scan time. CDNs, anycast, split-horizon DNS, load balancing, alternate ports, and untested addresses can produce different results. The scanner does not: