Skip to content

SQL Injection Prevention

The CPR backend uses Laravel's built-in protections against SQL injection.

How Laravel Prevents SQL Injection

Eloquent ORM

All Eloquent queries use parameterized queries (prepared statements) by default:

php
// Safe - parameters are automatically bound
Patient::where('last_name', $search)->get();

// Safe - Eloquent builder
Patient::query()
    ->search($search)
    ->filterByGender($gender)
    ->paginate($perPage);

Query Builder

The Laravel query builder also uses parameter binding:

php
// Safe - parameter binding
DB::table('patients')->where('email', $email)->first();

// Safe - whereIn with array
DB::table('patients')->whereIn('id', $ids)->get();

Form Request Validation

All input is validated via Form Request classes before reaching the database layer:

php
class StorePatientDataRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'last_name' => 'required|string|max:255',
            'email' => 'nullable|email',
            'birthdate' => 'required|date',
            // All fields validated and typed
        ];
    }
}

What to Avoid

Raw Queries with User Input

Never interpolate user input into raw queries

php
// DANGEROUS - SQL injection vulnerability
DB::select("SELECT * FROM patients WHERE name = '$name'");

// SAFE - Use parameter binding
DB::select('SELECT * FROM patients WHERE name = ?', [$name]);

Raw Expressions

Be careful with DB::raw():

php
// DANGEROUS
DB::raw("ORDER BY $userInput");

// SAFE - Validate against allowed values first
$allowedFields = ['last_name', 'first_name', 'created_at'];
$sortField = in_array($field, $allowedFields) ? $field : 'created_at';

The AbstractFilterableRepository already validates sort fields:

php
protected function validateSortField(?string $field): string
{
    return in_array($field, $this->getAllowedSortFields())
        ? $field
        : $this->getDefaultSortField();
}

Best Practices

  1. Always use Eloquent or the query builder - Never write raw SQL with user input
  2. Use Form Requests for validation - Validate all input before processing
  3. Use the repository pattern - All queries go through repositories with validated parameters
  4. Validate sort/filter fields - The AbstractFilterableRepository validates against allowed field lists
  5. Use $request->validated() - Only use validated data, never raw $request->input()

CPR - Clinical Patient Records