Please don't open a public issue for a security problem. Use GitHub's private vulnerability reporting on this repository (Security → Report a vulnerability). If that's unavailable, open a normal issue saying only that you have a security report and asking for a contact — no details.
Vibe Hero answers Claude Code permission prompts. It never widens what an agent is allowed to do — deny and ask rules in your Claude Code settings are evaluated independently and still apply — but it does decide whether a proposed command runs. That makes a few things security-relevant in ways they wouldn't be in an ordinary toy project.
The decision logic is the crown jewels. _decide() in
vibe_hero/server.py and emit_decision() in hooks/vibe_hero_hook.py
are the only code that can approve anything. A change making _decide()
return allow for unintended input would silently turn a review tool into
an auto-approver — the failure would be invisible, because everything
would appear to work. Changes to those two functions get security review,
and the test suite deliberately asserts what must not be approved:
bare strums, unmapped chords, non-strum events.
The bridge has no authentication. It binds to 127.0.0.1:8787, so it
isn't reachable from the network, but any process running as you on the
same machine can POST to it. Such a process can't approve anything on its
own — only a physical strum produces a decision — but it could register a
request and have your strum answer its prompt instead of Claude Code's.
Don't bind the bridge to anything but loopback, and don't forward the port.
Fail-open is intentional. Any failure produces no decision and falls
back to Claude Code's keyboard prompt. This is the correct trade-off here:
a hook that fails closed would either hang your session or auto-approve.
Never "fix" a failure path by making it emit allow.
This is a young project; only the latest main receives fixes.
In scope: anything that causes a command to be approved without a deliberate gesture, remote access to the bridge, or the hook emitting a decision it wasn't given.
Out of scope: the fact that a physical guitar can be strummed by someone standing next to you. Physical access is outside the threat model.