Saltar al contenido

Protección contra SQL Injection

En esta página

El SQL injection ocurre cuando un valor externo es concatenado en la cadena de la query antes de llegar a la base de datos. Al usar sql"...", Zolo nunca concatena: toda interpolación {expr} se convierte en un ? posicional y el valor se envía por separado a través del driver. La base de datos recibe la estructura de la query por un canal y los datos por otro — los metacaracteres SQL en el valor se tratan como texto, no como código.

El payload clásico '; DROP TABLE users; -- se inserta como variable en una query sql"...". La tabla permanece intacta y no se encuentra ninguna fila.

08-injection-safe.zolo
Playground
// Feature: `sql"..."` interpolations are *bound parameters*, not concatenated

// Syntax: `sql"SELECT ... WHERE x = {evil}"` — at compile time the

// `{evil}` becomes `?` and the value is sent as a parameter. SQL

// metacharacters in the value are literal, not parsed.

// When to use: ALWAYS. Never build queries with `+` or interpolation

// outside `sql"..."`. This file demonstrates why.


use std::database::Database

let db = Database.open("sqlite://:memory:")?
defer db.close()

db.execute(sql"CREATE TABLE users (name TEXT)")?
db.execute(sql"INSERT INTO users VALUES ('alice')")?
db.execute(sql"INSERT INTO users VALUES ('bob')")?

// The classic injection payload — in a string-concat builder it

// would terminate the query, drop the table, and comment out the rest.

// Inside `sql"..."` it's just a string parameter that doesn't match.

let evil = "'; DROP TABLE users; --"
let rows = sql"SELECT name FROM users WHERE name = {evil}".query(db)?
var count = 0
for _ in rows { count = count + 1 }
print("matched: {count}")

// expected: matched: 0


// Proof: the table is still there, both rows intact.

let total = sql"SELECT COUNT(*) FROM users".scalar(db)?
print("total: {total}")

// expected: total: 2


db.query("SELECT * FROM users") ?> .each(|u| print(u.name))

Requiere la CLI o el host de Zolo; ábrelo en el playground o ejecútalo localmente.

La regla práctica es simple:

  • Usa sql"..." (o ? + bindings) siempre que un valor provenga de fuera del código fuente.
  • Nunca construyas queries con + ni con interpolación fuera del literal sql"...".

Desafío

Intenta construir la misma query sin sql"..." usando concatenación de cadenas y observa qué ocurre con la tabla. ¿Qué mensaje de error emite Zolo?

Buscar en Zolo

9 resultados

enespt-br