Proteção contra SQL Injection
Nesta página
SQL injection ocorre quando um valor externo é concatenado na string da query
antes de chegar ao banco. Usando sql"...", o Zolo nunca concatena: toda
interpolação {expr} vira um ? posicional e o valor é enviado separadamente
pelo driver. O banco recebe a estrutura da query por um caminho e os dados por
outro — metacaracteres SQL no valor são tratados como texto, não como código.
O payload clássico '; DROP TABLE users; -- é inserido como variável numa
query sql"...". A tabela permanece intacta e nenhuma linha é encontrada.
// 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))
Requer a CLI/host do Zolo — abra no playground ou rode localmente.
A regra prática é simples:
- Use
sql"..."(ou?+ bindings) sempre que um valor vier de fora do código-fonte. - Nunca construa queries com
+ou com interpolação fora do literalsql"...".
Desafio
Tente construir a mesma query sem sql"..." usando concatenação de strings e
observe o que acontece com a tabela. Que mensagem de erro o Zolo emite?