Skip to content

Laravel SQL Injection Prevention

Learn how to prevent SQL Injection in Laravel with secure coding practices, Eloquent ORM, and Query Builder to protect your PHP applications.

Dasun Kalupahana 2 min read 1.2K views 0 comments

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=1 always 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 $email securely.

🔥 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 $orderId comes 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.

Ask the community

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.

Rate this post
5.0
Share

Enjoying the content?

If this article helped you, you can support the author with a coffee. It keeps new posts coming.

Buy me a coffee (opens in a new tab)

Comments 0

Be kind. Comments with links are reviewed before they appear.

No comments yet

Be the first to share your thoughts.

Get new articles in your inbox

Practical tutorials and deep dives, about once a week. No spam, unsubscribe anytime.

Privacy policy

Add DEV Talk to your Home Screen

  1. 1 Tap the Share button in Safari's toolbar.
  2. 2 Scroll down and tap Add to Home Screen.
  3. 3 Tap Add. Open it from the Home Screen to read like an app and to turn on notifications with the bell.

We use cookies to improve your experience and analyze traffic. By continuing, you agree to our Privacy Policy.