FlawOpen

flawopen.com/SQL Injection en C#/NHibernate

¿NHibernate protege frente a SQL Injection?

Guía de referencia
Respuesta breve

Un parámetro enlazado es como una ficha sellada en un formulario: la base de datos lo trata como dato, no como instrucción. Los parámetros HQL separan los valores. Interpolar texto no confiable en HQL o SQL vuelve a convertirlo en lenguaje de consulta.

INSEGURO — interpolar entrada en HQL
var hql =
  $"from User u where u.Id = {userId}";
var user = session.CreateQuery(hql)
  .UniqueResult<User>();
PROTEGIDO — enlazar el valor al parámetro HQL
var user = session.CreateQuery(
    "from User u where u.Id = :id")
  .SetParameter("id", userId)
  .UniqueResult<User>();

Enlaza valores; limita la estructura de la consulta

SetParameter() envía el valor por separado del texto HQL. Usa parámetros con nombre o posicionales para cada valor no confiable. Las consultas SQL nativas también admiten parámetros con nombre y posicionales; usa el método de enlace correspondiente de ISQLQuery (por ejemplo, SetString() para valores de texto). No representan nombres de entidades o propiedades, orden ni fragmentos de consulta: eso es estructura. Si el usuario puede elegir una propiedad, asigna su opción a fragmentos HQL fijos controlados por la aplicación. Parametrizar evita confundir datos con sintaxis, pero no determina si el usuario tiene permiso para acceder a los registros.

Preguntas frecuentes

¿Parametrizar HQL también autoriza el acceso a un registro?

No. Los parámetros protegen la sintaxis frente a los valores; la autorización debe limitar la consulta a registros accesibles para el usuario, por ejemplo, filtrando por cuenta o tenant autenticado.

Referencias

Véase también Inyección SQL (CWE-89): cómo funciona y cómo evitarla en cada lenguaje — flawopen.com Inyección NoSQL en MongoDB: filtros seguros SQL Injection en IDs numéricos: ¿riesgo? ¿Qué es una consulta parametrizada? ¿Prisma $queryRaw es seguro frente a SQL Injection? ¿Es segura la interpolación en where() de Rails? ¿Sequelize query() es seguro frente a SQL Injection?