From 215611822f27ec0134df6db96615dff4a199ed40 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Mon, 16 Feb 2026 11:38:17 +0000 Subject: [PATCH] Fix PR Probe result comments, update changelog --- .github/workflows/probe-comment.yml | 39 +++++++++++++ .github/workflows/probe.yml | 24 ++++---- CHANGELOG.md | 87 +++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/probe-comment.yml diff --git a/.github/workflows/probe-comment.yml b/.github/workflows/probe-comment.yml new file mode 100644 index 0000000..9a23036 --- /dev/null +++ b/.github/workflows/probe-comment.yml @@ -0,0 +1,39 @@ +name: Post Probe Comment + +on: + workflow_run: + workflows: ["Probe"] + types: [completed] + +jobs: + comment: + name: Post PR Comment + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + + permissions: + pull-requests: write + + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: probe-pr-comment + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Post or update comment + run: | + PR_NUMBER=$(cat pr-number.txt) + COMMENT_ID=$(gh api repos/${{ github.repository }}/issues/${PR_NUMBER}/comments \ + --jq '.[] | select(.body | contains("")) | .id' | head -1) + if [ -n "$COMMENT_ID" ]; then + gh api repos/${{ github.repository }}/issues/comments/$COMMENT_ID \ + -X PATCH -f body="$(cat probe-comment.md)" + else + gh pr comment "$PR_NUMBER" --body-file probe-comment.md + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/probe.yml b/.github/workflows/probe.yml index 38db35c..ce463d5 100644 --- a/.github/workflows/probe.yml +++ b/.github/workflows/probe.yml @@ -14,7 +14,6 @@ jobs: runs-on: ubuntu-latest permissions: - pull-requests: write contents: write actions: write @@ -284,19 +283,18 @@ jobs: name: probe-results path: probe-*.json - - name: Comment on PR + - name: Save PR metadata if: github.event_name == 'pull_request' && steps.changes.outputs.servers != '[]' - run: | - COMMENT_ID=$(gh api repos/${{ github.repository }}/issues/${{ github.event.number }}/comments \ - --jq '.[] | select(.body | contains("")) | .id' | head -1) - if [ -n "$COMMENT_ID" ]; then - gh api repos/${{ github.repository }}/issues/comments/$COMMENT_ID \ - -X PATCH -f body="$(cat probe-comment.md)" - else - gh pr comment ${{ github.event.number }} --body-file probe-comment.md - fi - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: echo '${{ github.event.number }}' > pr-number.txt + + - name: Upload PR comment + if: github.event_name == 'pull_request' && steps.changes.outputs.servers != '[]' + uses: actions/upload-artifact@v4 + with: + name: probe-pr-comment + path: | + probe-comment.md + pr-number.txt - name: Push to latest-results if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' diff --git a/CHANGELOG.md b/CHANGELOG.md index fdc5b9a..a349635 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,65 @@ All notable changes to Http11Probe are documented in this file. +## [2026-02-16] + +### Added +- **Sequence tests** — new multi-step test infrastructure (`SequenceTestCase`, `SequenceStep`, `SequenceSendPart`) for desync and smuggling detection with timed partial sends and behavioral analysis (#74) +- **26 new smuggling tests** — multi-step sequence tests for CL.TE, TE.CL, and desync detection: + - `SMUG-CLTE-SMUGGLED-GET` — CL.TE with embedded GET; multiple responses indicate boundary confusion + - `SMUG-CLTE-SMUGGLED-HEAD` — CL.TE with embedded HEAD + - `SMUG-CLTE-SMUGGLED-GET-CL-PLUS` — CL.TE smuggled GET with malformed CL (+N) + - `SMUG-CLTE-SMUGGLED-GET-CL-NON-NUMERIC` — CL.TE smuggled GET with non-numeric CL + - `SMUG-CLTE-SMUGGLED-GET-TE-OBS-FOLD` — CL.TE smuggled GET with obs-folded TE + - `SMUG-CLTE-SMUGGLED-GET-TE-TRAILING-SPACE` — CL.TE smuggled GET with TE trailing space + - `SMUG-CLTE-SMUGGLED-GET-TE-LEADING-COMMA` — CL.TE smuggled GET with TE leading comma + - `SMUG-CLTE-SMUGGLED-GET-TE-CASE-MISMATCH` — CL.TE smuggled GET with TE case mismatch + - `SMUG-TE-DUPLICATE-HEADERS-SMUGGLED-GET` — duplicate TE headers with embedded GET + - `SMUG-TECL-SMUGGLED-GET` — TE.CL with embedded GET (chunk-size prefix trick) + - `SMUG-DUPLICATE-CL-SMUGGLED-GET` — duplicate Content-Length with embedded GET + - `SMUG-GET-CL-PREFIX-DESYNC` — GET with CL prefix desync + - `SMUG-CLTE-DESYNC` — CL.TE desync with pause-based detection + - `SMUG-TECL-DESYNC` — TE.CL desync with pause-based detection + - `SMUG-CLTE-CONN-CLOSE` — CL.TE desync with Connection: close + - `SMUG-TECL-CONN-CLOSE` — TE.CL desync with Connection: close + - `SMUG-PIPELINE-SAFE` — safe pipeline baseline (no smuggling) + - `SMUG-CL0-BODY-POISON` — CL:0 body poison follow-up check + - `SMUG-GET-CL-BODY-DESYNC` — GET with CL body desync + - `SMUG-OPTIONS-CL-BODY-DESYNC` — OPTIONS with CL body desync + - `SMUG-EXPECT-100-CL-DESYNC` — Expect: 100-continue CL desync + - `SMUG-OPTIONS-TE-OBS-FOLD` — OPTIONS with obs-fold TE follow-up check + - `SMUG-CHUNK-INVALID-SIZE-DESYNC` — invalid chunk size + poison follow-up + - `SMUG-CHUNK-EXT-INVALID-TOKEN` — invalid token in chunk extension name + - `SMUG-CHUNK-SIZE-PLUS` — chunk size with leading plus sign + - `SMUG-CHUNK-SIZE-TRAILING-OWS` — chunk size with trailing whitespace +- **11 new compliance tests**: + - `COMP-RANGE-POST` — Range header on POST should be ignored (RFC 9110 §14.2) + - `COMP-UPGRADE-HTTP10` — Upgrade header in HTTP/1.0 request + - `COMP-DATE-FORMAT` — Date header format validation (RFC 9110 §5.6.7) + - `COMP-VERSION-CASE` — HTTP version case sensitivity (RFC 9112 §2.6) + - `COMP-LONG-URL-OK` — long URL within valid range should be accepted + - `COMP-SPACE-IN-TARGET` — space in request target should be rejected + - `COMP-DUPLICATE-CT` — duplicate Content-Type headers + - `COMP-TRACE-SENSITIVE` — TRACE method security sensitivity (RFC 9110 §9.3.8) + - `COMP-RANGE-INVALID` — invalid Range header format + - `COMP-ACCEPT-NONSENSE` — nonsensical Accept header value + - `COMP-POST-UNSUPPORTED-CT` — POST with unsupported Content-Type +- **FastEndpoints framework** — new test server added to the probe suite (#70) +- **Local probe script** — `scripts/probe-local.sh` for running probes against local servers +- **Sequence tests UI** — probe results page displays sequence test steps with per-step request/response details + +### Changed +- **SMUG-CLTE-PIPELINE and SMUG-TECL-PIPELINE** — re-evaluated scoring and validation logic +- **GenHTTP server** — clean-up and simplification (contributed by Andreas Nägeli) +- **RFC Requirement Dashboard** — updated with all 37 new tests and counts + +### Fixed +- **Traefik server** — fixed POST / to echo request body (contributed by SAILESH4406, #79) +- **Sequence test UI rendering** — fixed display of multi-step test results on probe results page +- **Second read from wire** — improved response capture with additional socket read for slow/partial responses (#71) +- **PR comment score** — fixed score calculation in probe workflow CI comments +- **NGINX server** — fixed implementation (#63) + ## [2026-02-14] ### Added @@ -13,6 +72,9 @@ All notable changes to Http11Probe are documented in this file. - **`RfcLevel` enum** — `Must`, `Should`, `May`, `OughtTo`, `NotApplicable` classification for every test case - **RFC Level annotations** — all tests across Compliance, Smuggling, MalformedInput, and Normalization suites annotated with their RFC 2119 requirement level - **Verbose Probe workflow** — new `probe-verbose.yml` GitHub Action for manual single-server probing with `--verbose` output, triggered via `workflow_dispatch` with a server name input (#60) +- **Giscus comments** — added comment system to website documentation pages +- **AI Contribution guide** — `AGENTS.md` for AI-agent contributions and `add-with-ai-agent` docs page +- **RFC Requirement Dashboard page** — comprehensive per-test RFC requirement tracking with counts and cross-references - **9 new RFC 9110 compliance tests** sourced from [mohammed90/http-compliance-testing](https://github.com/mohammed90/http-compliance-testing): - `COMP-HEAD-NO-BODY` — HEAD response must not contain a message body (RFC 9110 §9.3.2, MUST) - `COMP-UNKNOWN-METHOD` — unrecognized method should be rejected with 501/405 (RFC 9110 §9.1, SHOULD) @@ -40,6 +102,31 @@ All notable changes to Http11Probe are documented in this file. - **Method extraction** — handles leading CRLF in raw requests and tab-delimited request lines; non-HTTP pseudo-methods (PRI) shown as '?' - **Category-scoped filters** — Method and RFC Level filters now only show options relevant to the current category page +## [2026-02-13] + +### Added +- **Server configuration pages** — per-server docs pages showing Dockerfile, source code, and config files for all 36 tested servers (`docs/content/servers/`) (#28) +- **Clickable server names** — server names in the probe results table and summary bar chart now link to their configuration page +- **Sticky first column** — server name column stays pinned to the left edge while scrolling horizontally through result tables +- **Collapsible sub-groups** — group headers in result tables are now clickable to collapse/expand, with a chevron indicator and a "Collapse All / Expand All" toggle button +- **Row-click detail popup** — clicking a server row opens a modal showing that server's results for the current table in a vertical layout (Test, Expected, Got, Description) with section and table name in the header +- **Truncation notice** — tooltip and modal now show a `[Truncated]` notice at the top when raw request/response data exceeds the 8,192-byte display limit +- **Header normalization section** — new test category for header normalization tests (#32) +- **"Add a Framework" section improvements** — expanded documentation for adding new server frameworks (#42) + +### Changed +- **Scrollable tooltips** — hover tooltips are now interactive and scrollable for large payloads (removed `pointer-events:none`, increased `max-height` to `60vh`) +- **Larger click modal** — expanded from `max-width:700px` to `90vw` and `max-height` from `80vh` to `85vh` to better accommodate large request/response data +- Raw request capture now includes truncation metadata when payload exceeds 8,192 bytes +- Raw response capture now includes truncation metadata when response exceeds 8,192 bytes +- **Test re-evaluation** — reviewed and re-scored multiple tests for RFC alignment (#29) + +### Fixed +- **Kestrel server** — fixed HEAD and OPTIONS headers allowed (#39) +- **Node.js server** — fixed errors in Express server (#37) +- **CLI and PR scores** — fixed score calculation in CLI output and PR comments +- GenHTTP server re-enabled in probe suite + ## [2026-02-12] ### Added