Consultas seguras: evitando SQL injection no MTA
SQL injection é uma das falhas mais antigas — e ainda comuns — em sistemas com banco de dados. Em um servidor de MTA, pode permitir que um jogador roube contas, altere dinheiro ou apague tabelas inteiras.
Como o ataque acontece
Quando o código monta a consulta concatenando textos vindos do jogador:
-- NUNCA FAÇA ISSO
dbQuery(callback, db, "SELECT * FROM contas WHERE usuario = '" .. usuario .. "'")
Se o jogador digitar como usuário algo como ' OR '1'='1, a consulta muda de sentido. Com textos mais elaborados, é possível ler e alterar dados indevidamente.
Entradas perigosas vêm de: nome de usuário no login, nome do personagem, textos de anúncios, nomes de facção, descrições — qualquer texto digitado. E o nome do jogador (getPlayerName) também pode conter caracteres especiais.
A solução: parâmetros com ?
As funções de banco do MTA aceitam parâmetros. O MTA escapa os valores automaticamente:
dbQuery(callback, db, "SELECT * FROM contas WHERE usuario = ?", usuario)
dbExec(db, "UPDATE contas SET dinheiro = ? WHERE id = ?", novoSaldo, idConta)
dbExec(db, "INSERT INTO logs (conta, acao, valor) VALUES (?, ?, ?)", idConta, "pagamento", valor)
?→ valor (texto é escapado e colocado entre aspas; números ficam como números);??→ identificador (nome de tabela ou coluna), escapado com crases.
Montando consultas dinâmicas
Precisa montar uma consulta em partes? Use dbPrepareString:
local sql = dbPrepareString(db, "SELECT * FROM veiculos WHERE dono = ?", idConta)
if filtroModelo then
sql = sql .. dbPrepareString(db, " AND modelo = ?", filtroModelo)
end
dbQuery(callback, db, sql)
Nomes de colunas vindos do usuário
Nunca use diretamente. Use uma lista permitida:
local ORDENACOES = { dinheiro = true, nivel = true, horas = true }
if not ORDENACOES[coluna] then coluna = "nivel" end
dbQuery(callback, db, "SELECT nome, ?? FROM contas ORDER BY ?? DESC LIMIT 10", coluna, coluna)
Camadas extras de proteção
- Usuário de banco com permissões mínimas (sem
DROP, sem acesso a outros bancos, se possível); - Validação de tamanho e formato dos textos antes de salvar;
- Backups frequentes — se algo passar, você recupera;
- Senhas com hash (
passwordHash), nunca em texto puro.
Revise código herdado
Gamemodes antigos e resources baixados frequentemente têm consultas concatenadas. Procure por .. dentro de dbQuery/dbExec e corrija.
Hospede seu servidor com a VittHost
Todos os planos MTASA-BR da VittHost incluem 1 banco MySQL. Servidores no Brasil, painel Pterodactyl, proteção DDoS, downloads acelerados por nginx dedicado e teste grátis de 3 dias.