Skip to content

feat(web-security): add HTTP desync tooling and smuggling skill - #125

Merged
GangGreenTemperTatum merged 1 commit into
mainfrom
ads/cap-1188-improve-http-desync-tools-and-skills-for-web-security
Aug 20, 2026
Merged

feat(web-security): add HTTP desync tooling and smuggling skill#125
GangGreenTemperTatum merged 1 commit into
mainfrom
ads/cap-1188-improve-http-desync-tools-and-skills-for-web-security

Conversation

@GangGreenTemperTatum

Copy link
Copy Markdown
Contributor

Ports the http-desync-smuggling research (11 confirmed mechanism families from PortSwigger's HTTP Terminator) into web-security as a Dreadnode toolset plus a companion skill.

What's added

tools/desync.pyDesyncTools, four tools:

Tool Purpose
desync_fingerprint Which body-framing primitives the stack accepts — Server/CDN, TE chunked/identity/gzip, duplicate Content-Length, CL on bodyless GET. Seven probes run concurrently; a failed probe omits its field rather than aborting the fingerprint.
desync_build_payload Byte-exact raw HTTP/1.1 for 11 families. Content-Length and chunk sizes are computed from the real byte count.
desync_probe_cache Cache-layer detection plus cache-key membership — decides whether a confirmed desync escalates to cache poisoning.
desync_analyze_responses Classify victim-response-theft captures (session cookies, JWT, bearer, CSRF, PII) into a severity. Values redacted; full secrets never returned.

skills/http-desync-smuggling/SKILL.md — the 11 families with per-family family slugs, tool-driven phases, the interleaved-victim validation algorithm, and a permutation table.

Cross-refs added from te0-request-smuggling and response-queue-poisoning; all Chain With targets verified to exist.

Changes from the source material

  • Payload construction is new. The source had none — the skill carried hand-written HTTP blocks with hardcoded Content-Length: 50 values that don't match their bodies. An agent copying those sends a malformed request and reads the resulting 400 as "not vulnerable." Lengths and chunk sizes now derive from real byte counts.
  • Async with concurrent probes instead of sequential blocking calls with sleep(1) between cache GETs. Fingerprint completes in ~0.4s.
  • Uniform null-omitted dict returns instead of mixed dataclass/str, per the repo's tool-authoring rules.
  • proxy is a per-call arg, not a hardcoded Caido default — a Toolset field would be unreachable to the LLM.
  • Dropped feedback_loop.py / db_fingerprint.py. SQLite glue for HTTP Terminator's own campaign DB, no consumer here.

Verification

  • 97 new tests — payload byte-correctness per family, redaction, severity ordering, probe behaviour against a mocked transport.
  • Full capability suite: 429 passed.
  • just validate clean; tools 44 → 48, skills 81 → 82. Remaining warnings (caido-cli, burp, caido_proxy) are pre-existing on main.
  • Unit tests can't prove framing is wire-correct, so each built payload was also sent over a raw TLS socket to a live server. All eleven drew a semantic parser response (400 on CL/TE conflict, 501 on unknown TE, 405/200 otherwise) with no resets or hangs.

Reviewer notes

  • unkeyed_headers is a lead, not a fact. The Age-differential heuristic can't distinguish "header isn't in the cache key" from "Age just didn't move." A cache_key_method field states this inline so an agent doesn't report it as confirmed.
  • gitleaks caught the original test fixtures (synthetic JWT + session value scanning as real secrets). They're now built programmatically rather than allowlisted, so the hook keeps working for genuine leaks.
  • verify=False on probes is deliberate and documented in the module docstring: targets under test routinely present self-signed or expired certs, and a verification failure would mask the framing behaviour being measured.
  • Version bumped 1.9.01.10.0 (additive public surface).

Ports the http-desync-smuggling research (11 confirmed mechanism families
from PortSwigger's HTTP Terminator) into the capability as a Dreadnode
toolset plus a companion skill.

tools/desync.py — DesyncTools with four tools:

  desync_fingerprint       which body-framing primitives the stack accepts
                           (Server/CDN, TE chunked/identity/gzip, duplicate
                           Content-Length, CL on bodyless GET). Seven probes
                           run concurrently; a failed probe omits its field
                           rather than aborting the fingerprint.
  desync_build_payload     byte-exact raw HTTP/1.1 for 11 families. Content-
                           Length and chunk sizes are computed from the real
                           byte count, which is the bug agents hit when
                           hand-writing these.
  desync_probe_cache       cache-layer detection plus cache-key membership,
                           which decides whether a confirmed desync escalates
                           to cache poisoning.
  desync_analyze_responses classify victim-response-theft captures (session
                           cookies, JWT, bearer, CSRF, PII) into a severity.
                           Values are redacted; full secrets never returned.

Changes from the source script: async with concurrent probes rather than
sequential blocking calls with sleeps; uniform null-omitted dict returns
instead of mixed dataclass/str; payload construction added (the source had
none — payloads were hand-written in the skill prose); proxy is a per-call
arg instead of a hardcoded Caido default, so the agent controls routing.

Verified each built payload over a raw TLS socket against a live server:
all eleven get a semantic parser response (400 on CL/TE conflict, 501 on
unknown TE, 405/200 otherwise) with no resets, confirming wire-correct
framing.

97 tests covering payload byte-correctness per family, redaction, severity
ordering, and probe behaviour against a mocked transport. Full capability
suite: 429 passed.

The skill documents the interleaved-victim validation algorithm including
the erratic-domain baseline check, which is the step that separates a real
desync from the false positives this class is notorious for.
@GangGreenTemperTatum
GangGreenTemperTatum merged commit a82a413 into main Aug 20, 2026
5 checks passed
GangGreenTemperTatum added a commit that referenced this pull request Aug 20, 2026
PR #125 (HTTP desync tooling) merged to main first and shipped 1.10.0, so
this branch's own 1.10.0 bump collided.

Resolution:

  version     1.10.0 -> 1.11.0, since 1.10.0 is already published on main.
              Both branches independently claimed 1.10.0; git auto-merged
              the identical strings without flagging it, so the bump would
              have silently republished a shipped version.

  description keeps both contributions — "HTTP desync/request smuggling"
              from #125 and the four-Caido-surfaces wording from this
              branch. Playbook count set to 82, the actual skill directory
              count on the merged tree (both sides were stale: "81" here,
              "80+" on main).

No code conflicts: the two PRs touch disjoint files apart from the manifest.

Verified on the merged tree: 479 tests pass (429 from main + 50 Caido tests
from this branch), capability validates at 1.11.0 with 48 tools / 82 skills,
and the caido_proxy "defined no tools" warning present on main is resolved
by this branch's changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant