FlawOpen

flawopen.com/SQL Injection/¿Basta con un ORM?

¿Basta con usar un ORM para prevenir la inyección SQL?

Página de referencia
Respuesta breve

Un ORM es como una cocina que prepara pedidos desde un formulario: su constructor habitual mantiene los valores separados. Un atajo de SQL sin procesar es otra entrada con reglas propias. Comprueba la API exacta antes de confiar en valores interpolados.

INSEGURO — texto del usuario dentro del SQL de FromSqlRaw
var sql = $"SELECT * FROM dbo.Blogs WHERE Url = '{url}'";
var rows = await context.Blogs
    .FromSqlRaw(sql)
    .ToListAsync();
// User text is inserted into SQL before execution.
SEGURO — enlaza con FromSql (EF Core 7+)
var rows = await context.Blogs
    .FromSql($"SELECT * FROM dbo.Blogs WHERE Url = {url}")
    .ToListAsync();
// EF Core 7+: interpolation becomes a SQL parameter.

El patrón, en todos los ORM

Los constructores de consultas ORM y las API SQL sin procesar no forman una única frontera de seguridad. La documentación oficial muestra la vinculación segura en Django raw(sql, params), SQLAlchemy text() con parámetros separados, condiciones con marcadores en Rails, EF Core FromSql (7+) / FromSqlInterpolated, GORM Raw(sql, args...) y $queryRaw con etiqueta de plantilla en Prisma. Las API difieren: FromSqlRaw es seguro con parámetros separados, pero no si se inserta texto del usuario en la cadena SQL; $queryRawUnsafe también puede enlazar valores aparte, pero concatenar texto no confiable sigue siendo inseguro. El nombre del método no demuestra cómo trata los valores. Enlaza cada dato con el mecanismo documentado. Los identificadores SQL y la estructura no admiten parámetros; elígelos de una lista fija controlada por la aplicación. Las guías siguientes detallan cada contrato.

Qué exige realmente "basta"

FAQ

¿Los métodos de SQL sin procesar siempre son inseguros?

No. Algunas API SQL sin procesar enlazan valores pasados por separado, y algunas API seguras reciben valores interpolados como parámetros. FromSql de EF Core 7+ acepta un FormattableString interpolado; FromSqlRaw requiere parámetros separados. $queryRawUnsafe de Prisma también puede enlazar valores, pero no sanea el texto SQL que construyas. Comprueba el contrato y mantén los valores no confiables fuera de la estructura SQL.

Referencias

Véase también Inyección SQL (CWE-89): cómo funciona y cómo evitarla en cada lenguaje — flawopen.com ¿Knex.js es seguro frente a SQL Injection? MyBatis ${} vs #{}: evitar SQL Injection MySQLi vs PDO: prepared statements seguros ¿NHibernate protege frente a SQL Injection? Inyección NoSQL en MongoDB: filtros seguros SQL Injection en IDs numéricos: ¿riesgo?