ai · tutorial · agents
Code That Passes Lint and Ships a Vuln
Green lint plus green tests can still ship injection, auth bypass, or leaked secrets. The quiet-fail classes plus the review that catches them. Inside.

The green build with a hole in it
The agent's PR passes lint. The tests are green. The preview renders beautifully.
Wednesday, a user exports another user's invoices by changing an ID in the URL.
Thursday, a secret shows up in an error trace. Friday, a crafted search string dumps a table.
Every check passed because every check inspects form.
Syntax is valid.
Types align.
Tests assert what the agent wrote.
Security lives in meaning. Who may read this row? Where does this string run?
The holes that pass every gate
| Hole | What it looks like | What the gate says |
|---|---|---|
| Missing ownership check | A clean route with no user check | Green |
| Injection | A tidy query builder | Green |
| Secret in a log | Helpful debug output | Green |
| Paywall early-return | A refactored handler | Green |
| Mass assignment | A spread operator save | Green |
Agent code is especially prone, for three reasons.
Tests assert the agent's assumptions. The agent writes tests proving its code does what it intended, including the vulnerability. A test can happily assert that someone else's row returns 200.
Refactors drop guards silently. Move code between files and the paid-access check, the ownership check and the redaction can vanish. The diff shows a clean move.
Helpfulness leaks secrets. Agents log generously. Full payloads. Error stacks with context. Each line is a possible broadcast.
What to do
Enforce ownership where the data is read.
A route that asks for "this user's order" cannot forget the check. A route that asks for "this order" can.
Put the check in the lowest layer, so it survives refactors and new endpoints.
Keep secrets out of output. Decide which values must never appear in a log, an error or an alert. Review every new output path against that list.
Then review the guard set on every diff. Four questions, asked of each agent PR that touches routes or data.
- Does every new read filter by the caller?
- Does every new route check paid access?
- Does any new log or error carry request context?
- Is there a test where user B must not see user A's data?
None of this is answerable by lint.
The adversary test carries the load. Each PR gains one test asserting that the forbidden thing fails.
Green then means safe, not just well shaped.
A Monday habit
Pick your riskiest route. Ask the four questions of it.
Write the adversary test it does not have. Run it. Watch it fail, then make it pass.
One route a week. In a month the dangerous ones are covered.
What it costs
Ten minutes of review per PR. A habit of keeping ownership checks low.
That slows an agent a little. One cross-user leak costs more trust than weeks of features earn.
Know this first
BoringPush does not redact secrets from logs for you. Review habits still matter. So does the adversary test.
Green lint is not proof of safe.
Why BoringPush is the way to do this
Green is only the start.
BoringPush ships guards for open redirects, for one user reading another's record, and for runaway requests.
Its rules put the access check first in every route.
Safe by default. Proven by your own tests.
FAQ
Is a quiet vulnerability just prompt engineering gone wrong?
No. It is a category gap, not a wording bug. No prompt makes a linter see meaning or makes a test assert a case nobody asked for.
The fix is structural (ownership in the data layer) plus procedural (guard review and adversary tests). Better prompts help a little; fences help completely.
Should I run an automated scanner instead of reviews?
Alongside, not instead. Scanners catch known patterns such as outdated dependencies and classic injection shapes. Reviews catch meaning such as ownership and business-logic abuse.
Scanner-green plus review-skipped is exactly the failure this post describes. Layer them: a scanner on every push, a review on every PR.
How do I write adversary tests agents won't neutralize?
Order them explicitly in the task: user B requests user A's order and expects a refusal. Then read the test's assertion before you read the implementation.
A test that asserts the leak passes is worse than no test. Treat the test file as the place where safety gets specified.
Do small solo apps really get attacked?
Probed constantly, targeted rarely. Bots try ID swapping, injection strings and secret harvesting against every app they find.
The classes here defend against the probes, which are certain, and cost little against targeted attackers, who are rare.
What about dependencies?
Same quiet-fail problem, one step removed. Supply chain is the sixth class: trusted code you did not write, running with your keys loaded. Keep dependencies few, audit them on a schedule, and review additions as carefully as your own code.
When does security review become a dedicated role?
Past about five engineers, or with regulated data such as health or finance. Checklist discipline stops scaling when reviewers rotate. Until then, four questions and one adversary test per PR beat most startups' actual practice.
Keep reading
- Endless AI Slop Is Killing Code Reviews (Fix Inside) — the volume problem this silence hides inside
- 40% of Vibe Apps Leak Data With No Login (Checklist) — the leak statistics behind the urgency
- Thin Routes: Why Agents Fear Your 250-Line Handler — small files make guard review possible
+ all the boring stuff (analytics, auth, SQLite ↔ Supabase, full marketplace, webhooks)
Command from your phone.
Built so autonomous AI agents build what you want without breaking what's already paying you.
- Built-in analytics — cookie-free mode, $0 forever, no PostHog bill
- SQLite ↔ Supabase: one setting, same field names
- Full digital marketplace & feedback boards included
- 3 payment rails: Stripe, LemonSqueezy & Dodo Payments
- Agent fences: lint gate, read-only data access, auto-rollback
- Ship from your phone via SSH & WireGuard/Tailscale in under a minute
$199
Get BoringPushOne-time payment · Lifetime updates · Unlimited projects.
Keep reading


