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.
Comment corriger cette vulnérabilité
Stratégies de prévention pour SQL Injection basées sur 7 règles de détection 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)
Trouvez les vulnérabilités dans votre code
Utilisez Shoulder pour scanner votre code à la recherche de patterns SQL Injection. 7 règles.
# Scan with Shoulder CLI npx @shoulderdev/cli trust --cwe=89 # Or scan entire project npx @shoulderdev/cli trust .
Règles de Détection (7)
Ce qu'il faut surveiller lors des revues de code
Ces patterns indiquent des vulnérabilités potentielles SQL Injection. Recherchez-les lors des revues de code et des audits de sécurité.
Motifs de revue manuelle
Lors de la revue manuelle du code, cherchez ces motifs dangereux.
query = + concaténation de chaînesexecute(f"... or execute("..." +raw_query, rawQuery, executeRaw${ or #{ à l'intérieur de chaînes SQLComment pensent les experts en sécurité
Le modèle mental qu'utilisent les professionnels de la sécurité lors de la revue de cette vulnérabilité.
Cartographier les points d'entrée
Paramètres d'URL, corps POST, en-têtes, cookies, téléversements de fichiers.
Tracez le flux de données
Suivez l'entrée à travers le code. Est-elle assainie ?
Identifiez les puits
Where queries are executed: execute(), query()
Vérifier les frontières de confiance
Surveillez les données stockées utilisées dans les requêtes.
Scannez votre base de code pour SQL Injection
Shoulder CLI trouve les motifs vulnérables dans toute votre base de code.