diff options
Diffstat (limited to 'PLAN.md')
| -rw-r--r-- | PLAN.md | 71 |
1 files changed, 67 insertions, 4 deletions
@@ -864,7 +864,70 @@ because it came from a plugin rather than raw traffic. core-engine change to how requests get dispatched, not something a plugin protocol should be shaped around. -Next: Phase 1's plugins themselves (Autorize- and Param-Miner- -equivalents first, since they validate the simple subscribe-act-tag -path before anything gets built on top of it), then the live-RPC -protocol addition for JWT Editor/SAML Raider. +### Wire-format consistency fix (found while building the first plugin) + +Writing PLUGINS.md as an authoritative external spec surfaced a real, +pre-existing inconsistency: `store.Summary`/`Entry`/`EntryTag`/ +`WSMessage`, `rules.Rule`, `scope.Rule`, and `clientcert.Cert` had no +JSON struct tags at all, so Go's default marshaling serialized them as +PascalCase (`"ID"`, `"StartedAt"`) while the rest of the protocol +(`EntryDetail`'s own fields, every `Request`/`Response` wrapper field) +uses snake_case. Confirmed live against a real daemon before touching +anything: a raw socket `list` request came back with `"ID"`, +`"StartedAt"`, `"StatusCode"` - exactly the mismatch suspected. Nothing +outside this repo's own Go code consumes this wire format yet, so +adding tags now (rather than documenting the wart) was a free, purely +additive fix - every affected struct now tags snake_case throughout, +consistent with the rest of the protocol, verified with a full +build/vet/test pass afterward. + +### First plugin shipped: `plugins/authcheck` + +An Autorize-style authorization checker, and the reference +implementation `PLUGINS.md` points to. Deliberately speaks the wire +protocol directly - its own local `request`/`response`/`summary`/ +`entryDetail` structs mirroring the real ones field-for-field, not +imported - rather than reaching into `internal/ipc`, even though nothing +stops a Go plugin from doing that. The point isn't style: it's proof +that the documented protocol is actually sufficient on its own, since +that's the only thing a non-Go plugin author has to work with, and the +best available check against silently depending on some Go-internal +convenience that never made it into the docs. + +For every proxied (not `source: "repeater"` - see below) request +carrying an `Authorization` or `Cookie` header, resends it via `repeat` +with that header stripped and compares status classes: if the original +succeeded (2xx/3xx) and the anonymous resend *also* succeeded, that's a +likely missing-function-level-access-control bug, tagged +`authcheck:bypass` with the two status codes and which header was +stripped as the tag's JSON data. Matches Burp's own Autorize default of +only surfacing likely findings, not logging every check performed. +Explicitly guards against reprocessing its own resends (`Repeat` +records `source: "repeater"`, filtered out on the subscribe feed) - +without that, the plugin would try to authcheck its own control-group +requests, which is at best wasted work and at worst misattributes a +finding to the wrong entry. + +Simplified relative to real Autorize: Autorize's other mode swaps in a +SECOND, lower-privileged identity's session rather than going fully +anonymous, which catches cross-account IDORs an anonymous-only check +can't (an endpoint might correctly reject "no credentials" while still +leaking another user's data to a validly-authenticated-but-wrong-user +request). That needs a second credential as input this reference +version doesn't take - a natural, small extension (a `-low-priv-cookie` +flag, one more resend variant, one more tag) once wanted. + +Verified live end to end against a real daemon, a real Python origin +server with one endpoint that looks like it enforces auth but doesn't +(vulnerable by design) and one that actually does (the control case): +the broken endpoint was correctly tagged, the properly-secured one was +correctly left untouched - no false positive - confirmed both via the +stored tag data (`go run` against the daemon directly) and visually in +the TUI (tmux, real keystrokes): the `Tags` column badge, `T`'s tag +list, and the tag detail view's JSON-colorized data, ANSI-verified, all +showing the plugin's actual findings. + +Next: the remaining Phase 1 plugins (Param Miner, Backslash Powered +Scanner, Retire.js - no new protocol capability needed, same pattern +`authcheck` already validates), then the live-RPC protocol addition for +JWT Editor/SAML Raider. |