srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/PLAN.md
diff options
context:
space:
mode:
Diffstat (limited to 'PLAN.md')
-rw-r--r--PLAN.md71
1 files changed, 67 insertions, 4 deletions
diff --git a/PLAN.md b/PLAN.md
index 68b6e56..529503d 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -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.