elgibor-solution/laravel-database-encryption
Transparently encrypt sensitive model attributes in Laravel with no query changes. Eloquent casts encrypt on save and decrypt on read, keeping data secure at rest while still supporting lookups on encrypted values through hashed indexes. Simple config, key management, and drop-in integration for exi...
This release is a security patch (SQL injection prevention), so treat the upgrade as mandatory rather than optional. Start by confirming which version you're on and what the diff actually changes.
Pin the floor, not just the ceiling. In composer.json, move the constraint from ^1.0 to ^1.1 so a fresh composer install on any machine cannot resolve back to a vulnerable 1.0.x:
composer require vendor/package:"^1.1" --no-update
composer update vendor/package --with-dependencies
Read the diff before you deploy. SQL-injection fixes usually land in one of two shapes, and they have very different upgrade implications:
composer diff vendor/package # or diff the tagged releases on the repo
First use case to verify: any endpoint where user-controlled input reaches the package's query layer — search boxes, sortable table headers, filter dropdowns, report builders, API query-string passthrough. That is precisely the surface this release is hardening, and it's where you should point your first regression test.
If your app never passes user input into the package (pure internal calls with hard-coded arguments), the upgrade is still worth doing for supply-chain hygiene, but the risk window is small and you can ship it on your normal cadence.
Upgrade in isolation. Bump only this package (composer update vendor/package --with-dependencies), run the suite, commit composer.json and composer.lock together. If your CI has composer audit or Dependabot-style scanning, confirm the advisory clears after the bump — that's your proof the fix is actually in the resolved tree, not just in your constraint.
Audit call sites for raw fragments. Grep your own code for the package's query-building entry points, then look for anything that smells like string concatenation into SQL:
grep -rn "whereRaw\|orderByRaw\|selectRaw\|DB::raw\|havingRaw" app/
If your integration passes sort columns, sort direction, or filter keys straight from $request->query(), that's the injection vector — and note that parameter binding does not protect identifiers. Bindings only cover values. A 1.1.0 that binds values will not save you from ?sort=id; DROP TABLE users-- if the package interpolates the column name. Enforce an allowlist on your side:
$sortable = ['created_at', 'name', 'status'];
$sort = in_array($request->query('sort'), $sortable, true)
? $request->query('sort')
: 'created_at';
$direction = $request->query('dir') === 'asc' ? 'asc' : 'desc';
Write the regression test that would have caught the original bug. Payloads in feature tests are cheap insurance against a future refactor reintroducing interpolation:
public function test_sort_parameter_is_not_interpolated_into_sql(): void
{
$this->get('/reports?sort=' . urlencode("id) UNION SELECT password FROM users--"))
->assertOk()
->assertJsonMissing(['password' => fn ($v) => $v !== null]);
$this->assertDatabaseCount('users', 0);
}
Handle the rollout order for long-lived processes. If you run Octane, queue workers, or scheduler daemons, they hold the old code in memory. Restart them as part of the deploy (php artisan octane:reload, php artisan queue:restart) — otherwise part of your fleet keeps executing the vulnerable path while composer reports the patch as installed.
Sequence multi-service deploys deliberately. If several services share the package and one consumes another's output, deploy the producer first when the fix is behavioural (e.g. it now escapes a value that used to be returned raw). Otherwise the consumer parses double-escaped data for the duration of the rollout.
LIMIT/OFFSET, or direction keywords. If you assumed the patch makes the package safe against all query-string tampering, verify it. Those three cases need explicit allowlisting/(int) casting in your own layer regardless of package version.QueryException where interpolation previously produced a silently-empty result set. That turns a previously-invisible bug into a 500 in production — good, but it should be a 422 you handle deliberately, not a surprise.~1.0 and assume you're covered. Tilde constraints resolve >=1.0.0 <1.1.0 and will happily stay on the vulnerable branch. Commit the lockfile and make sure CI installs from it.composer.json can serve an old vendor/; key on composer.lock or both.DB::listen() or ->dd() on the builder shows whether user input arrives as a ? binding or is interpolated into the SQL string. If a payload appears verbatim in the logged SQL, that code path was not fixed by this release and needs your own allowlist.How can I help you explore Laravel packages today?