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.
So behebst du diese Schwachstelle
Präventionsstrategien für SQL Injection basierend auf 7 Shoulder-Erkennungsregeln.
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)
Finden Sie Schwachstellen in Ihrem Code
Verwenden Sie Shoulder, um Ihren Code nach SQL Injection-Mustern zu scannen. 7 Regeln.
# Scan with Shoulder CLI npx @shoulderdev/cli trust --cwe=89 # Or scan entire project npx @shoulderdev/cli trust .
Erkennungsregeln (7)
Worauf bei Code-Reviews zu achten ist
Diese Muster weisen auf potenzielle SQL Injection-Schwachstellen hin. Achten Sie bei Code-Reviews und Sicherheitsaudits darauf.
Manuelle Review-Muster
Bei der manuellen Code-Review nach diesen gefährlichen Mustern suchen.
query = + String-Verkettungexecute(f"... or execute("..." +raw_query, rawQuery, executeRaw${ or #{ innerhalb von SQL-StringsWie Sicherheitsexperten denken
Das mentale Modell, das Sicherheitsexperten beim Review dieser Schwachstelle verwenden.
Einstiegspunkte kartieren
URL-Parameter, POST-Bodies, Header, Cookies, Datei-Uploads.
Datenfluss verfolgen
Verfolge die Eingabe durch den Code. Wird sie bereinigt?
Senken identifizieren
Where queries are executed: execute(), query()
Vertrauensgrenzen prüfen
Achte auf gespeicherte Daten, die in Abfragen verwendet werden.
Scanne deine Codebasis nach SQL Injection
Shoulder CLI findet anfällige Muster in deiner gesamten Codebasis.