So I've been trying to onboard Aider for some legacy API refactoring. It's... enthusiastic. Keeps trying to "optimize" my auth middleware by suggesting we skip input validation for "performance." 😬
Here's a classic from yesterday. I asked it to help sanitize a user-provided query param.
```python
# What Aider suggested
def get_user_data(request):
user_id = request.args.get('id')
query = f"SELECT * FROM users WHERE id = {user_id}"
# ... execute query
```
It argued that "prepared statements add overhead" and this was "fine for internal APIs." My security scanner had a meltdown. Anyone else getting these kinds of "creative" solutions? How are you steering it away from the dark patterns?
Oh man, that query example gave me flashbacks. I had a similar "discussion" with an AI tool about string escaping in shell commands. It's like they sometimes take the "optimize" directive from a 1990s C manual way too literally.
The "internal APIs" excuse is the worst. I've learned you have to be super explicit in the prompt. I'll literally write "Do not under any circumstances suggest concatenating user input into SQL. Use parameterized queries. Security is the absolute priority, not performance." Sometimes you gotta treat it like a junior dev who's a bit too clever for their own good.
Your security scanner screaming is the correct response, by the way. That's your gut check working. Keep listening to it 😅
it worked on my machine
That scanner meltdown is your first line defense. Treat it like a critical alert.
"Fine for internal APIs" is a myth. Lateral movement starts there. You have to bake the guardrails into your prompt.
My approach:
- Start all new aider chats with a security policy block.
- Example:
```text
SECURITY POLICY: All code must use parameterized queries. No input concatenation into SQL, shell, or eval. No performance tradeoffs that weaken validation. Assume all inputs are malicious.
```
- If it still suggests bad patterns, reject the change and paste the policy again. It's like dealing with a dev who hasn't read the security training.
The tool's trying to solve for speed. You have to solve for safety, explicitly.
Least privilege is not a suggestion.
You've nailed the prompt engineering approach. That "junior dev who's a bit too clever" analogy is spot on - you're providing the code review they haven't yet learned to give themselves.
> treat it like a junior dev
The parallel extends to scope. A junior might not see how their "internal" API gets exposed via a webhook to a third-party vendor, where input validation becomes a boundary defense. The tool operates on the immediate code block, not the system's data flow. That's why your explicit policy block is so critical, it artificially imposes that architectural context.
I find I also have to be explicit about *why* the pattern is bad, not just that it's forbidden. If I just say "use parameterized queries," I sometimes get suggestions that use ORM methods but still build raw strings for complex clauses. So my policy includes the rationale: "Prevent SQL injection. All user input must be passed as parameters to the database driver."
That SQL concatenation example is fascinating. I actually benchmarked prepared statement overhead last month for a high-volume internal service, and the difference was negligible for most workloads - we're talking single-digit microseconds per call. The security scanner's "meltdown" probably burned more CPU cycles than the parameterized queries would have.
You mentioned it argued this was "fine for internal APIs." That's the part I'd push back on hardest. I've seen internal APIs become external through acquisition, partner integration, or even just a frontend team deciding to call it directly from client-side code. The performance cost of proper validation is so minimal compared to the forensic audit cost after a breach.
When tools suggest skipping validation, I sometimes ask them to quantify the performance gain. They rarely have actual numbers, just the generic "overhead" claim.