FlawOpen

flawopen.com/Inyección SQL en Go/GORM Raw SQL e inyección SQL

¿GORM Raw() evita la inyección SQL? Parámetros enlazados en Go

CWE-89: SQL InjectionPágina de referencia
Respuesta breve

Imagina el marcador de posición como un sobre cerrado para un valor: el controlador envía el valor separado de las instrucciones SQL. GORM Raw() puede enlazarlo de forma segura si mantienes el marcador en la consulta y pasas el valor como argumento. Formatear la entrada del usuario dentro de la cadena SQL mezcla el sobre con las instrucciones y puede cambiar la consulta.

NO SEGURO
// El texto controlado por el usuario se convierte en sintaxis SQL
db.Raw(fmt.Sprintf(
  "SELECT * FROM users WHERE id = %s",
  userID,
)).Scan(&user)
SEGURO
// El controlador enlaza userID como valor
db.Raw(
  "SELECT * FROM users WHERE id = ?",
  userID,
).Scan(&user)

SQL Raw seguro y enlace de parámetros en GORM

GORM y database/sql de Go enlazan valores cuando los marcadores permanecen en el SQL y los argumentos se pasan aparte, por ejemplo db.Where("name = ?", userInput) o db.Raw("SELECT ... WHERE id = ?", userID). Un marcador representa un valor, no sintaxis SQL: los nombres de tabla y columna, el orden y los operadores no se protegen al enlazarlos como valores. Elige los identificadores dinámicos de una lista permitida fija. Métodos como Order, Select, Table y Raw pueden permitir inyección si concatenas entradas en sus fragmentos SQL.

Cómo buscar en el código

rg -n --glob '*.go' '\.(Raw|Exec|Order|Select|Table)\s*\(' . rg -n --glob '*.go' 'fmt\.(Sprintf|Sprint)' .

Preguntas frecuentes sobre GORM Raw SQL y parámetros

¿Los métodos encadenables de GORM siempre son seguros?

No. Las condiciones que pasan valores aparte, como Where("name = ?", input), usan enlace de parámetros. Concatenar la entrada en la condición o pasarla como sintaxis SQL sin procesar aún puede inyectar consultas. Algunos métodos aceptan identificadores o fragmentos SQL sin escapar; revisa sus argumentos y permite la estructura dinámica mediante listas permitidas.

¿Un marcador puede enlazar el nombre de una tabla o columna?

No. Los marcadores representan valores de datos. Para identificadores u órdenes dinámicos, elige opciones fijas definidas por la aplicación e inserta en la estructura SQL solo la constante validada.

Fuentes oficiales y referencias

Véase también Inyección SQL (CWE-89): cómo funciona y cómo evitarla en cada lenguaje — flawopen.com ¿Basta escapar comillas para evitar SQL Injection? ¿Basta con usar un ORM para prevenir la inyección SQL? ¿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?