Skip to content

Add ZeitHawk, a standalone client-side HTTP security testing toolkit - #4

Merged
BruceLittle merged 8 commits into
mainfrom
claude/stoic-archimedes-qnrnxl
Sep 17, 2026
Merged

BruceLittle merged 8 commits into
mainfrom
claude/stoic-archimedes-qnrnxl

Conversation

@BruceLittle

Copy link
Copy Markdown
Owner

Summary

  • Adds tools/zeithawk/index.html, a self-contained, dependency-free HTML page with Repeater, Intruder, Decoder, and Comparer tools built in the spirit of Burp Suite's core tools, for manual security testing of authorized targets.
  • Adds tools/zeithawk/README.md documenting the tools and the inherent constraints of a browser-only client (CORS, forbidden request headers).
  • Not part of the Rails app's runtime — it's a standalone static page with no build step or backend dependency.

Test plan

  • Open tools/zeithawk/index.html directly in a browser
  • Repeater: send the prefilled httpbin.org GET request and confirm status/headers/body render
  • Intruder: run the prefilled numeric-payload attack against httpbin.org and confirm results populate
  • Decoder: confirm the Base64 example decodes/encodes correctly, spot-check a hash op
  • Comparer: confirm the prefilled diff renders added/removed lines
  • History: confirm sent requests appear and reload into Repeater on click

🤖 Generated with Claude Code

https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn


Generated by Claude Code

A self-contained HTML page with Repeater, Intruder, Decoder, and Comparer
tools in the spirit of Burp Suite, for manual testing of authorized
targets. No build step or backend; runs entirely in the browser.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn

Copy link
Copy Markdown
Owner Author

dependency-audit (bundler-audit) is failing on this PR's head commit, but it's not caused by this diff — the PR only adds tools/zeithawk/index.html and tools/zeithawk/README.md; Gemfile/Gemfile.lock are untouched.

The failure is bundler-audit's advisory DB (last updated 2026-09-16, the day before this PR) picking up newly-disclosed CVEs against gem versions already pinned in Gemfile.lock on main:

Since main's CI hasn't re-run since these were disclosed, this would fail identically there today — it's a pre-existing dependency issue, not something introduced by this change. I don't see an existing fix/PR to port, and bumping these versions is out of scope for a PR that only adds a static tooling page, so I'm not pushing it here. Proposed patch for a follow-up: bump the four gems above to the listed patched versions in Gemfile/Gemfile.lock and re-run bundle exec rspec + bundle exec bundler-audit check.

All other checks (test, lint, brakeman, terraform-validate) are green on this PR.


Generated by Claude Code

Mirrors the AI Tool Finder artifact's escalation pattern: a mailto link
prefilled with the Repeater target, for requesting written sign-off
before testing something not yet authorized.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn
The "Request Security authorization" mailto still opens with zero setup;
this adds a best-effort, silently-no-op-until-configured POST alongside it
that logs the same request to Firestore via a small Apps Script web app,
so there's a durable, searchable record beyond one inbox. Includes a
"View recent authorization requests" JSONP read-back panel in the banner.

tools/apps-script-backend/ has the deployable Code.gs + appsscript.json
and a README walking through GCP project setup, Firestore (Native mode),
and web app deployment, plus the CORS/no-auth tradeoffs of an anonymous
Apps Script endpoint.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn
Deployed tools/apps-script-backend/Code.gs under project "zeithawk"
(568770471889) via clasp, with a Firestore Native-mode database created
in that project. Wires the resulting /exec URL into APPS_SCRIPT_URL so
the "Request Security authorization" logging and "View recent
authorization requests" panel are live instead of a no-op.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn
Drops the "Request Security authorization" mailto button, its Apps
Script + Firestore logging call, and the "recent authorization
requests" read-back panel from the banner. ZeitHawk goes back to just
the disclaimer text with no escalation flow attached.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn
The Intruder XSS payload preset included the literal string
'<script>alert(1)</script>'. Browsers close a <script> element the
instant they see that byte sequence in the raw source, regardless of
JS string context — so this silently truncated ZeitHawk's own script
tag right there, breaking every feature after the Intruder tool
(Decoder, Comparer, History, and the tab bar itself never rendered).

Caught by actually loading the page in a real browser instead of just
checking the extracted script text with `node --check`, which can't
see this kind of HTML-parsing gotcha. Escaping the slash
(<script>alert(1)<\/script>) keeps the runtime string identical while
no longer matching the HTML closing-tag sequence in source.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn
Fixes the dependency-audit failure flagged on PR #4 (pre-existing on
main, unrelated to ZeitHawk, but folding the fix in here since it's
already the active PR):

- rails/activestorage 8.1.3 -> 8.1.3.1: CVE-2026-66066 (possible
  arbitrary file read / RCE in variant processing)
- json 2.20.0 -> 2.21.2: CVE-2026-71847 (parser dereferences a freed
  buffer on truncated duplicate-key streams). Pinned "< 3" — bundler's
  first resolution jumped to json 3.0.2, which broke JSON.parse call
  sites elsewhere in the stack (18 spec failures, all 500s from an
  ArgumentError). The 2.x line has the fix too.
- loofah 2.25.1 -> 2.25.2: three javascript: URI sanitizer bypasses
  (GHSA-5qhf-9phg-95m2, GHSA-8whx-365g-h9vv, CVE-2026-73490)
- rails-html-sanitizer 1.7.0 -> 1.7.1: CVE-2026-73648 (possible XSS)

Also fixes two rubocop offenses surfaced by rubocop itself moving
1.88.1 -> 1.91.0 as part of this resolution (Gemfile gem ordering, and
api_token.rb's disable/enable pair collapsed to a single trailing
directive per Style/DirectiveScope).

Verified: 65/65 specs green, 0 rubocop offenses, 0 brakeman warnings,
bundler-audit reports no vulnerabilities.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn

Copy link
Copy Markdown
Owner Author

Update: bumped the four flagged gems in this same PR (activestorage/rails → 8.1.3.1, json → 2.21.2, loofah → 2.25.2, rails-html-sanitizer → 1.7.1). json's first resolution jumped to 3.0.2, which broke JSON parsing in the request stack (18 spec failures) — pinned it < 3 to stay on the patched 2.x line instead. Verified locally: 65/65 specs green, 0 rubocop offenses, 0 brakeman warnings, bundler-audit check reports no vulnerabilities.


Generated by Claude Code

An inline SVG mark (ellipse head, triangular hooked beak, brow ridge,
eye with a glint highlight) rendered next to the title text, themed
via new --hawk-head/--hawk-beak/--hawk-eye/--hawk-glint tokens defined
across all three theme blocks (light, dark, explicit data-theme) so it
holds up in both themes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkupxCaLk9Nnq24YhigdAn
@BruceLittle
BruceLittle merged commit 0b32263 into main Sep 17, 2026
10 checks passed
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.

2 participants