A05: Inyeccion (Blog)
¿Que es la inyeccion?
La inyeccion ocurre cuando una entrada no confiable se interpreta como codigo, fragmento de query o comando. En Laravel suele aparecer como inyeccion SQL, inyeccion de comandos y XSS cuando se rompe el escape por defecto de Blade.
Laravel advierte explicitamente que nunca debes pasar input controlado por el usuario a Rule::unique()->ignore(...), porque puede crear riesgo de inyeccion SQL.
Fallo tipico en Laravel (blog)
- SQL crudo con input interpolado.
- Uso inseguro de
ignore()en validacion. - Ejecucion insegura de comandos/shell.
- Inputs dinamicos inseguros para columnas/ordenamiento al listar posts.
- Stored XSS al renderizar comentarios como HTML con
{!! !!}.
Impacto
- Robo o corrupcion de datos.
- Toma de cuenta via scripts inyectados (XSS).
- Ejecucion remota de codigo via inyeccion de comandos.
- Impacto de cumplimiento e incident response.
Remediacion en Laravel 12
- Prefiere Eloquent / Query Builder con bindings.
- Evita
DB::raw()salvo que sea inevitable. - Nunca uses input del usuario como nombre de columna, order/sort, expresiones raw o comandos shell sin allowlists estrictas.
- Usa Form Requests y valida antes de construir la consulta.
- Mantén Blade escapado por defecto; usa
{!! !!}solo para HTML confiable y sanitizado.
Arreglo concreto
Bindings seguros (sin interpolacion de strings):
$query->where('email', $request->string('email'));
Ordenamiento seguro para listados de posts con allowlist:
$allowedSorts = ['title', 'created_at']; $sort = in_array($request->sort, $allowedSorts, true) ? $request->sort : 'created_at'; $query->orderBy($sort);
Evita stored XSS en comentarios (mantén Blade escapado por defecto):
<p>{{ $comment->body }}</p> {{-- Malo: output raw de input no confiable --}}{{-- <p>{!! $comment->body !!}</p> --}}
Enfoque de patron de diseno
Usa Strategy para reglas de filtrado/ordenamiento seguras en lugar de concatenar fragmentos de query en controllers. Mantiene allowlists y mapeos centralizados, explicitos y testeables.
use Illuminate\Database\Eloquent\Builder; interface SortStrategy{ public function apply(Builder $query, string $direction = 'desc'): Builder;} final class SortByCreatedAt implements SortStrategy{ public function apply(Builder $query, string $direction = 'desc'): Builder { return $query->orderBy('created_at', $direction); }} final class SortByTitle implements SortStrategy{ public function apply(Builder $query, string $direction = 'asc'): Builder { return $query->orderBy('title', $direction); }} // Uso: mapea input del usuario a estrategias conocidas$sorts = [ 'created_at' => new SortByCreatedAt(), 'title' => new SortByTitle(),]; $sortKey = $request->string('sort')->toString();$sort = $sorts[$sortKey] ?? $sorts['created_at']; $query = $sort->apply($query);