Laravel SQL injection guide: Practical examples included

Laravel SQL injection guide: Practical examples included


Want to know how to protect your Laravel applications? Dive into our latest blog post, where we guide you through the best practices for Laravel security. Explore how these techniques can not only enhance the security of your web applications but also bring tangible benefits to your development journey.

In this guide, Escape's security research team has gathered the most crucial tips to protect your Laravel applications from potential breaches, focusing on how to implement protection against SQL injections. Our goal is to empower you to create more resilient and efficient Laravel projects. Let's get started!

What is SQL injection?

SQL injection is a type of cyber attack where malicious SQL code is inserted into input fields of a web application, exploiting vulnerabilities in the application's database layer. The attacker can manipulate or retrieve data, modify database entries, and even execute administrative operations.

SQL injection attacks also affect major organizations.

In 2011,  Sony’s network suffered a severe SQL Injection attack, compromising its digital infrastructure. Around 77 million PlayStation Network accounts were affected, costing Sony an estimated $170 million.

In October 2023, hackers were observed trying to breach cloud environments through Microsoft SQL Servers vulnerable to SQL injection. This lateral movement technique has been previously seen in attacks on other services like VMs and Kubernetes clusters.

Why Laravel might be vulnerable to SQL injections?

Here are some reasons Laravel applications might be prone to SQL injections:

  1. Raw queries: Using raw SQL queries instead of Laravel's query builder or Eloquent ORM can increase the risk of SQL injection if input is not properly sanitized.
  2. Insufficient input validation: Lack of proper validation of user inputs can expose applications to injection attacks. Always validate and sanitize user inputs before using them in database queries.
  3. Insecure query building: Improper use of Laravel's query builder or Eloquent ORM, such as concatenating user inputs directly into queries without using parameterized bindings, can lead to vulnerabilities.
  4. Failure to use parameterized statements: Not using parameterized statements in prepared queries can expose applications to SQL injection. Parameterized queries automatically handle input sanitization, reducing the risk of injection attacks.
  5. Outdated libraries or framework versions: Using outdated versions of Laravel or associated libraries might expose applications to known security vulnerabilities. Regularly update to the latest versions to benefit from security patches.
💡
Wondering if your APIs built with Laravel are vulnerable to SQL injections? Test it with Escape - an automated API security testing tool.

Examples of SQL Injections in Laravel SQL injections and how to prevent them

A real-life example of SQL injection in Laravel

Let's take a look at real-life examples of Laravel SQL injection to understand better how it can occur.

💡
A practical learner? Check out a vulnerable Laravel app.

Let's begin with an example involving user input in a search feature. Imagine we have a search form where users can enter keywords to find products. The code might look something like this:

$searchTerm = $_GET['search'];
$results = DB::select("SELECT * FROM products WHERE name LIKE '%$searchTerm%'");

Now, if an attacker enters a malicious input like '; DROP TABLE products; --, the SQL statement would become:

SELECT * FROM products WHERE name LIKE ''; DROP TABLE products; --%'

This would result in the deletion of the entire "products" table. This example highlights the importance of proper input validation and sanitization to prevent SQL injection attacks.

A beginner in Laravel? Check out the following explanation:

How to prevent SQL injection in Laravel

The OWASP Cheatsheet is a great starting point to enhance the security of your Laravel applications against SQL injections.

It covers:

  • Eloquent ORM SQL Injection Protection
  • Raw query SQL injection
  • Column Name SQL Injection
  • Validation Rule SQL Injection

It is especially valuable since it covers a broad spectrum of the most common and impactful security vulnerabilities. More than that, one of the key strengths of the OWASP Cheatsheets are their regular updates.

Input validation & sanitization

One common SQL injection vulnerability in Laravel is the lack of proper input validation. When user input is not properly validated or sanitized, it can be manipulated to include malicious SQL statements. For example, if a user enters a malicious SQL query into a search field, it could bypass any input filtering and potentially execute unauthorized database actions.

Always validate user input for such situations like this:

use App\Models\User;

$request->validate(['sortBy' => 'in:price,updated_at']);
User::query()->orderBy($request->validated()['sortBy'])->get();

This can be prevented by using Laravel's built-in validation features, such as validating input against specific rules and using parameterized queries to bind user input to SQL statements. By implementing these practices, developers can protect their Laravel applications from SQL injection vulnerabilities.

  1. Create a new Laravel route and controller for the search functionality:
php artisan make:controller SearchController
  1. In your SearchController.php file, create a method to handle the search:
// app/Http/Controllers/SearchController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class SearchController extends Controller
{
    public function search(Request $request)
    {
        // Validate user input
        $request->validate([
            'search_term' => 'required|string',
        ]);

        // Sanitize the input (optional, but recommended)
        $searchTerm = $request->input('search_term');

        // Use a parameterized query to prevent SQL injection
        $results = DB::select("SELECT * FROM your_table WHERE column_name = :searchTerm", ['searchTerm' => $searchTerm]);

        // Handle the search results
        // ...

        return view('search_results', ['results' => $results]);
    }
}

In this example, we use Laravel's validation feature to ensure that the search_term input is a non-empty string. Then, we use a parameterized query to safely execute the SQL query, binding the user input to the :searchTerm placeholder.

  1. Create a route in web.php to handle the search:
// routes/web.php

use Illuminate\Support\Facades\Route;

Route::get('/search', 'SearchController@search');
  1. Create a view for displaying search results (resources/views/search_results.blade.php), and render the results as needed.

By following this approach, Laravel automatically validates and sanitizes user input, and the use of parameterized queries ensures that the user input is safely embedded into the SQL statement, mitigating the risk of SQL injection attacks.

Limiting database permissions

To prevent SQL injection in Laravel, it is important to limit the database permissions. By granting only the necessary permissions to the database user, we can restrict the potential damage that can be caused by SQL injection attacks.

One way to achieve this is by using the principle of least privilege, where the database user only has the necessary permissions to perform its intended tasks.

For example, if the user only needs to read data from a specific table, we can grant it read-only access to that table and restrict its ability to modify or delete data. By doing so, even if an SQL injection attack is successful, the attacker's capabilities will be limited to the permissions granted to the database user, reducing the potential impact of the attack.

Limiting database permissions in Laravel involves using the built-in features of Laravel's Eloquent ORM and database migrations. Here's how to set it up using Spatie package:

// Example using Spatie Laravel Permission
$role = Role::create(['name' => 'admin']);
$permission = Permission::create(['name' => 'edit_users']);
$role->givePermissionTo($permission);

Regular updates and patches

Regular updates and patches are crucial in preventing SQL injection attacks on Laravel applications. The developers of Laravel constantly release updates and patches to fix any vulnerabilities found in the framework. Laravel's community is active in reporting and fixing security issues.

When a vulnerability is discovered, the Laravel team promptly releases a patch to address the issue. As a developer, it is important to stay updated with these releases and promptly apply the patches to your application. Here's an example illustrating the importance of regular updates:

// Vulnerable code without updates
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$result = DB::select($query);

// Fixed code with updates
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = ?";
$result = DB::select($query, [$id]);

In this example, the vulnerable code directly uses the user input in the SQL query, making it susceptible to SQL injection attacks. However, by regularly updating Laravel and applying patches, you can use Laravel's built-in query bindings feature, as shown in the fixed code.

Conclusion

In conclusion, securing applications built with Laravel, especially against SQL injections, is a multifaceted task requiring a comprehensive approach to mitigate potential risks and ensure the confidentiality, integrity, and availability of data.

It is essential to tailor security strategies to the specific needs of your application, considering factors like the nature of data exchanged, user authentication requirements, and the level of exposure to potential threats. Regular security audits, automated API security testing with tools like Escape, and staying informed about emerging security practices within the Laravel community contribute to an adaptive and resilient security posture.


Want to learn more? 💡