A large share of new Laravel code is now written by an assistant. Claude Code and GitHub Copilot scaffold controllers, models and migrations in seconds, and most of the time the result looks right and passes the tests. That is exactly the problem. AI-generated Laravel code is fluent, and fluency hides the security mistakes the framework was designed to prevent. The generator is fast; the judgment about whether the code is safe still has to come from a person. You are the quality control.
This article is part of the Laravel Security Review cluster. It looks at how AI code generation changes the security picture, and how to review what the assistant hands you.
What the assistant gets right, and where it drifts
AI assistants are genuinely good at Laravel boilerplate: resource controllers, form requests, factories, tests. They follow the framework’s conventions when the conventions are common in their training data. The drift shows up in the security-sensitive corners, because a model optimises for code that looks plausible, not code that is safe. These are the patterns I see reintroduced most often.
Raw queries in place of the query builder
Ask an assistant for a complex or dynamic query and it will often reach for a raw string, interpolating variables directly. Eloquent’s bindings are what keep you safe from SQL injection, and the generated code quietly steps outside them.
// What the assistant often writes
DB::select("SELECT * FROM users WHERE email = '{$request->email}'");
// What it should be
DB::select('SELECT * FROM users WHERE email = ?', [$request->email]);
Authentication without authorization
This is the single most common gap. The assistant generates a controller that checks the user is logged in and then acts on whatever record the route received, with no check that this user may touch this record. The code works in every demo and fails the moment someone changes an ID in the URL.
public function update(Request $request, Post $post)
{
// The assistant stops here. The missing line is the security control:
$this->authorize('update', $post);
$post->update($request->validated());
}
Wide-open mass assignment
To make an example “just work,” a model is often generated with protected $guarded = [];, which turns off mass-assignment protection entirely. A request can then set any column, including is_admin. Prefer an explicit $fillable allow-list.
Secrets, unescaped output and disabled protections
Assistants will hardcode an API key into a seeder or config file, print user input with {!! $value !!}, or add a route to the CSRF exception list to make a form submit. Each is a small convenience that removes a protection Laravel gives you for free. They also tend to reproduce patterns from older Laravel versions, because that is what most of the training data contains.
This is a review problem, not a tooling problem
It is tempting to treat these as bugs in the tool. They are not. An assistant amplifies whatever discipline you bring to it. Point it at a codebase with policies, form requests and a security checklist, and it will tend to follow those examples. Point it at a blank file with a vague prompt, and it will give you the most common answer on the internet, which is rarely the most secure one. The security of AI-assisted Laravel work is decided by the review, and the review is theory made practical: the same principles that always governed secure PHP, now applied to code you did not type yourself.
A review workflow for AI-generated Laravel code
- Prompt for security up front. Ask for authorization checks, validated requests and parameter bindings by name. You get what you ask for, so ask.
- Read every generated query and controller. Confirm bindings over interpolation, an
authorize()call on every record action, and an explicit$fillable. These three checks catch the majority of what slips through. - Use AI to review AI. A second pass where you ask the assistant to find security issues in its own output catches a surprising amount, as long as you still verify the findings yourself.
- Run the mechanical checks.
composer auditfor dependencies, a grep for hardcoded secrets, and your test suite. Automate what a human should not have to remember. - Diff against the checklist. Before merging, run the generated feature against the Laravel security checklist and the OWASP Top 10 in Laravel.
I wrote a book about exactly this
This way of working, treating yourself as the quality control for AI-generated code, is the subject of my book You Are the Quality Control: Preventing Data Loss and Building Secure Software with Claude Code and GitHub Copilot. Chapter 6 works through PHP and Laravel with a complete project skeleton, Chapter 11 covers using Claude Code as your security reviewer, Chapter 12 covers GitHub Copilot guardrails, and Chapter 14 is about building a quality-control culture on a team so this discipline does not depend on one careful person. The book’s code and details are on GitHub.
If you want the shorter version of the argument first, my article on the security risks of AI coding tools is the companion piece to the book.
Related
- Laravel Security Review: a practical walk through reviewing and hardening a Laravel application, area by area, with every guide in this cluster in one place.
- You Are the Quality Control: the book on securing AI-assisted development.
- Security Risks of AI Coding Tools
- A Laravel Security Checklist for Production
- Preventing the OWASP Top 10 in Laravel
- Securing Authentication and Authorization in Laravel