SQL Injection is one of the oldest and most dangerous web application vulnerabilities. If you’re building Laravel applications, you’re in luck — Laravel’s Eloquent ORM and query builder offer strong defenses. But to stay secure, you still need to understand the risks and how to avoid them.
In this article, we’ll cover:
- What SQL Injection is
- Why it happens
- How Laravel protects you
- Real examples of safe and unsafe code
- Tips for maximum safety
💡 What is SQL Injection?
SQL Injection happens when untrusted input ends up directly in your SQL queries. Attackers can inject malicious SQL commands to:
- Read sensitive data
- Modify or delete records
- Bypass authentication
- Escalate privileges
For example, a vulnerable query might look like:
DB::select("SELECT * FROM users WHERE id = $id");
If $id is set to:
1 OR 1=1 --
Look carefully:
OR 1=1always evaluates to true, so it ignores the id filter.- The
--comments out the rest of the query.
Test Result:
I created simple command for test it.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class SqlIjectionTestCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'test:sql-injection';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Test SQL Injection';
/**
* Execute the console command.
*/
public function handle()
{
// Test with malicious input
$maliciousInput = "1 OR 1=1 --";
// This should return all records
$result = DB::select("SELECT * FROM users WHERE id = {$maliciousInput}");
// If it returns all users, you have a vulnerability
$count = count($result);
$this->info("count: {$count}");
}
}
Output:

Which returns all users!
🧰 Laravel’s Built-in Protections
Laravel’s Eloquent ORM and Query Builder use prepared statements, which safely bind parameters instead of concatenating strings. This prevents injected code from being executed.
Example: Safe Query
$user = DB::table('users')->where('email', $email)->first();
Under the hood, Laravel does something like:
SELECT * FROM users WHERE email = ?
And binds your
🔥 Unsafe Code Examples (What NOT to Do)
Even in Laravel, you can still create vulnerabilities if you build raw SQL strings manually:
❌ Direct interpolation (Dangerous):
$results = DB::select("SELECT * FROM orders WHERE order_id = $orderId");
If
$orderIdcomes from user input, attackers can manipulate the query.
✅ Safe Code Examples
✅ Using Query Builder:
$results = DB::table('orders')
->where('order_id', $orderId)
->get();
✅ Using parameter binding:
$results = DB::select(
"SELECT * FROM orders WHERE order_id = ?",
[$orderId]
);
✅ Using Eloquent:
$order = Order::where('order_id', $orderId)->first();
All of these are safe because they never concatenate raw input.
Test Result:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class SqlIjectionTestCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'test:sql-injection';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Test SQL Injection';
/**
* Execute the console command.
*/
public function handle()
{
// Test with malicious input
$maliciousInput = "1 OR 1=1 --";
// This should return only the intended result, not all records
$result = DB::select("SELECT * FROM users WHERE id = ?", [$maliciousInput]);
// If it returns all users, you have a vulnerability
$count = count($result);
$this->info("count: {$count}");
}
}
Output:

🛠️ Tips for Staying Safe
Here are some guidelines to keep your Laravel apps secure:
🔹 Always use Eloquent or Query Builder.
🔹 Avoid raw SQL unless absolutely necessary.
🔹 When using DB::raw(), never include unescaped variables.
🔹 Validate and sanitize input wherever possible.
🔹 Use Laravel’s built-in validation rules.
🔹 Keep Laravel and dependencies up to date.
✨ Real Example: Safe Search
Let’s say you want to build a search that filters users by name.
Unsafe (Bad):
$search = $_GET['search'];
$users = DB::select("SELECT * FROM users WHERE name LIKE '%$search%'");
Safe (Good):
$search = $_GET['search'];
$users = DB::table('users')
->where('name', 'like', "%{$search}%")
->get();
Laravel handles binding and escaping automatically.
🧭 Conclusion
Laravel makes it easy to write secure database queries, but only if you follow best practices. Avoid string concatenation, leverage prepared statements, and validate user input.
By understanding how SQL Injection works and how to prevent it, you’re already far ahead in securing your Laravel applications.
📚 Further Reading
If you found this helpful, feel free to share or drop a comment. Happy coding with Laravel! 🧱✨
Free resources for this topic
Code snippets and fixes for this topic
Get one practical tip every week
New tutorials, fixes and free cheat sheets from DEV Talk, straight to your inbox. No spam, unsubscribe in one click.
Free download: Laravel interview questions (PDF)
Have a question about this post?
Ask the community: other developers and the author can answer.
Get notified about new articles
One click, no email needed. Turn it off anytime with the bell at the top.
Get new articles on your iPhone
Add DEV Talk to your Home Screen, open it, then tap the bell.
Enjoying the content?
If this article helped you, you can support the author with a coffee. It keeps new posts coming.
Comments 0
No comments yet
Be the first to share your thoughts.