Improper Neutralization of Special Elements used in an SQL Command
User input is concatenated directly into SQL queries, allowing attackers to modify the query logic and access or manipulate data. This is one of the oldest and most dangerous vulnerability classes, responsible for some of the largest data breaches in history.
Como corrigir esta vulnerabilidade
Estratégias de prevenção para SQL Injection baseadas em 7 regras de detecção do Shoulder.
Use parameterized queries with $1 (PostgreSQL) or ? (MySQL/SQLite) placeholders
func getUser(w http.ResponseWriter, r *http.Request) { userID := r.URL.Query().Get("id") - query := "SELECT * FROM users WHERE id = " + userID - rows, err := db.Query(query) + rows, err := db.Query("SELECT * FROM users WHERE id = $1", userID) // ... }
Use parameterized queries with placeholder syntax
- const query = `SELECT * FROM users WHERE id = '${req.params.id}'`; - await db.query(query); + const query = 'SELECT * FROM users WHERE id = $1'; + await db.query(query, [req.params.id]);
Use Prisma.sql tagged template for parameterized raw queries instead of regular template literals
- import { PrismaClient } from '@prisma/client'; - const prisma = new PrismaClient(); - - app.get('/api/users/search', async (req, res) => { - const { name } = req.query; - const users = await prisma.$queryRaw` - SELECT * FROM "User" WHERE name LIKE '%${name}%' - `; - res.json(users); - }); - // Attacker sends: name=' OR 1=1 -- + import { PrismaClient, Prisma } from '@prisma/client'; + const prisma = new PrismaClient(); + + app.get('/api/users/search', async (req, res) => { + const { name } = req.query; + const users = await prisma.$queryRaw( + Prisma.sql`SELECT * FROM "User" WHERE name LIKE ${`%${name}%`}` + ); + res.json(users); + });
Use parameterized queries with positional (?) or named (:param) placeholders instead of string interpolation
import { getManager } from 'typeorm'; app.get('/api/users/search', async (req, res) => { const { name, role } = req.query; const manager = getManager(); const users = await manager.query( - `SELECT * FROM users WHERE name = '${name}' AND role = '${role}'` - ); - res.json(users); - }); - // Attacker sends: name=' OR '1'='1' -- + 'SELECT * FROM users WHERE name = $1 AND role = $2', + [name, role] + ); + res.json(users); + });
Use parameterized GraphQL queries with variables instead of string formatting
from flask import request import graphene @app.route('/graphql', methods=['POST']) def graphql_endpoint(): - user_id = request.json.get('id') - query = f'{{ user(id: "{user_id}") {{ name email }} }}' - result = schema.execute(query) + query = request.json.get('query') + variables = request.json.get('variables', {}) + result = schema.execute(query, variables=variables) return jsonify(result.data)
Encontre vulnerabilidades no seu código
Use o Shoulder para escanear seu código em busca de padrões SQL Injection. 7 regras.
# Scan with Shoulder CLI npx @shoulderdev/cli trust --cwe=89 # Or scan entire project npx @shoulderdev/cli trust .
Regras de Detecção (7)
O que observar nas revisões de código
Estes padrões indicam vulnerabilidades potenciais de SQL Injection. Procure-os durante revisões de código e auditorias de segurança.
Padrões de revisão manual
Ao revisar código manualmente, procure por estes padrões perigosos.
query = + concatenação de stringsexecute(f"... or execute("..." +raw_query, rawQuery, executeRaw${ or #{ dentro de strings SQLComo especialistas em segurança pensam
O modelo mental que profissionais de segurança usam ao revisar esta vulnerabilidade.
Mapeie os pontos de entrada
Parâmetros de URL, corpos POST, cabeçalhos, cookies, uploads de arquivo.
Rastreie o fluxo de dados
Siga a entrada através do código. Ela é sanitizada?
Identifique os sumidouros
Where queries are executed: execute(), query()
Verifique as fronteiras de confiança
Observe dados armazenados usados em consultas.
Escaneie seu código para SQL Injection
O Shoulder CLI encontra padrões vulneráveis em todo o seu código.