SQL Injection Analyzer
| Analyzer ID | Category | Severity | Time To Fix |
|---|---|---|---|
sql-injection | 🛡️ Security | Critical | 30 minutes |
What This Checks
This analyzer detects potential SQL injection vulnerabilities in your Laravel application by identifying unsafe SQL query construction patterns:
- String concatenation in SQL queries (e.g.,
"WHERE id = " . $id) - Variable interpolation in SQL queries (e.g.,
"WHERE name = '$name'") - Missing parameter bindings when user input is present
- Unsafe usage of
DB::raw(),whereRaw(),selectRaw(), and similar methods - DB::unprepared() usage (inherently unsafe)
- Native query functions (
mysqli_query,pg_query) with concatenation/interpolation
What's NOT Flagged
The analyzer correctly recognizes these as safe:
- PDO/mysqli instantiation (
new PDO(),new mysqli()) - just connection setup - Prepared statement functions (
mysqli_prepare(),pg_prepare()) - secure by design - Parameter binding (
DB::select('WHERE id = ?', [$id])) - the recommended safe pattern - Static queries without variables (
DB::select('SELECT * FROM users'))
Why It Matters
SQL injection is one of the most critical security vulnerabilities (OWASP Top 10 #1) that can lead to:
- Complete data breach - Attackers can extract entire databases
- Data manipulation - Unauthorized modification or deletion of records
- Authentication bypass - Logging in as any user including administrators
- Privilege escalation - Gaining elevated system permissions
- Server compromise - In severe cases, complete system takeover
A single SQL injection vulnerability can compromise your entire application, making it critical to detect and fix these issues before deployment.
How to Fix
Quick Fix (5 minutes)
Replace string concatenation with parameter binding:
Before (❌):
use Illuminate\Support\Facades\DB;
public function search($userId)
{
// Vulnerable: String concatenation
$results = DB::select(
"SELECT * FROM users WHERE id = '" . $userId . "'"
);
}After (✅):
use Illuminate\Support\Facades\DB;
public function search($userId)
{
// Safe: Parameter binding with placeholders
$results = DB::select(
"SELECT * FROM users WHERE id = ?",
[$userId]
);
}Proper Fix (30 minutes)
Refactor to use Laravel's Query Builder or Eloquent ORM for automatic protection:
Before (❌):
public function searchUsers($name, $status)
{
// Multiple vulnerabilities
$query = "SELECT * FROM users WHERE name LIKE '%" . $name . "%'";
if ($status) {
$query .= " AND status = '" . $status . "'";
}
return DB::select($query);
}After (✅):
public function searchUsers($name, $status)
{
// Safe: Query Builder handles escaping automatically
$query = DB::table('users')
->where('name', 'like', '%' . $name . '%');
if ($status) {
$query->where('status', $status);
}
return $query->get();
}Best Practice (✅✅):
public function searchUsers(Request $request)
{
// Validate input first
$validated = $request->validate([
'name' => 'required|string|max:255',
'status' => 'nullable|in:active,inactive,pending',
]);
// Use Eloquent with validated data
return User::query()
->where('name', 'like', '%' . $validated['name'] . '%')
->when($validated['status'] ?? null, function ($query, $status) {
$query->where('status', $status);
})
->get();
}ShieldCI Configuration
The analyzer can be customized to recognize additional native database functions specific to your application. To configure them, publish the config:
php artisan vendor:publish --tag=shieldci-configThen in config/shieldci.php:
'analyzers' => [
'security' => [
'enabled' => true,
'sql-injection' => [
// MySQLi query execution functions to check for SQL injection
// Only functions that execute queries are checked (not prepare/connect/fetch)
'mysqli_functions' => [
'mysqli_query', // Default
'mysqli_real_query', // Default
'mysqli_multi_query', // Default
// Add any custom mysqli wrapper functions that execute queries
'custom_db_query',
],
// PostgreSQL query execution functions to check
'postgres_functions' => [
'pg_query', // Default
'pg_send_query', // Default
// Add any custom pg wrapper functions that execute queries
'custom_pg_execute',
],
],
],
],When to Customize
Only customize the function lists if you have custom query execution functions in your codebase.
Important: The analyzer only flags functions when SQL queries have concatenation or interpolation. Safe usage patterns are not flagged:
// ✅ NOT flagged - no concatenation
mysqli_query($conn, "SELECT * FROM users WHERE id = 1");
// ❌ FLAGGED - has concatenation
mysqli_query($conn, "SELECT * FROM users WHERE id = " . $userId);The default lists cover standard MySQLi and PostgreSQL query execution functions. You typically don't need to customize unless you have wrapper functions like custom_execute_query() or legacy_db_run().
References
- OWASP SQL Injection
- Laravel Query Builder Documentation
- Laravel Eloquent ORM
- CWE-89: SQL Injection
- PHP PDO Prepared Statements
Related Analyzers
- Debug Mode Analyzer - Debug mode can leak SQL queries in error messages
- Debug Log Level Analyzer - Prevents logging of SQL queries with sensitive data
- Mass Assignment Vulnerabilities Analyzer - Protects against mass assignment vulnerabilities
- XSS Vulnerabilities Analyzer - Detects cross-site scripting vulnerabilities
- CSRF Protection Analyzer - Ensures CSRF protection is enabled