FlawOpen

flawopen.com/SQL Injection en Ruby/ActiveRecord where()

¿Es segura la interpolación en where() de Rails?

Página de referencia
Respuesta breve

Imagina que SQL es un formulario con instrucciones fijas y casillas vacías para valores. Un parámetro vinculado rellena una casilla; la interpolación de Ruby inserta el texto de la solicitud en las instrucciones antes de que Rails pueda separar ambas partes. Mantén fija la estructura SQL y pasa los valores no confiables como parámetros.

UNSAFE
User.where(
  "id = #{params[:id]}"
)
SAFE
User.where(id: params[:id])
# or, for more complex conditions:
User.where("id = ?", params[:id])

Por qué la interpolación cambia la consulta

Ruby evalúa #{...} antes de que Active Record reciba la condición. Por ejemplo, where("id = #{params[:id]}") entrega a Rails una cadena SQL ya combinada; la entrada de la solicitud puede cambiar el predicado. Active Record documenta este patrón de construcción de cadenas como inseguro. Usa un hash para condiciones compatibles de igualdad, rango o subconjunto, o marcadores ? para otros predicados. Los marcadores vinculan valores, no identificadores ni palabras clave SQL; mantén fija la estructura de la consulta o elige identificadores mediante una lista de permitidos estricta.

Cómo revisar tu código

rg -n 'where\s*\(' app/
Revisa las coincidencias para encontrar datos de solicitudes interpolados o concatenados dentro de cadenas de condición. Brakeman informa riesgos de SQL Injection cuando su análisis detecta un flujo de datos inseguro; un análisis limpio no demuestra que todas las consultas sean seguras.

Preguntas frecuentes

¿Puedo usar condiciones hash para todas las consultas?

No. Las condiciones hash de Rails admiten igualdad, rango y subconjunto (IN). Para otros predicados, usa una condición SQL fija con valores vinculados, por ejemplo where("price > ?", amount). El enlace protege los valores; no vuelve seguros los nombres dinámicos de tablas, columnas ni fragmentos SQL.

Referencias

Véase también Inyección SQL (CWE-89): cómo funciona y cómo evitarla en cada lenguaje — flawopen.com ¿Sequelize query() es seguro frente a SQL Injection? ¿SQLAlchemy text() es seguro frente a SQL Injection? ¿La verificación de consultas de sqlx en compilación evita la inyección SQL? ¿Los procedimientos almacenados evitan la inyección SQL? ¿El QueryBuilder de TypeORM es seguro frente a SQL Injection? Django ORM y SQL Injection: patrones seguros