sql-injection-prevention

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SQL Injection Prevention

SQL注入防护

Overview

概述

Implement comprehensive SQL injection prevention using prepared statements, parameterized queries, ORM best practices, and input validation.
使用预编译语句、参数化查询、ORM最佳实践和输入验证实现全面的SQL注入防护。

When to Use

适用场景

  • Database query development
  • Legacy code security review
  • Security audit remediation
  • API endpoint development
  • User input handling
  • Dynamic query generation
  • 数据库查询开发
  • 遗留代码安全审查
  • 安全审计整改
  • API端点开发
  • 用户输入处理
  • 动态查询生成

Implementation Examples

实现示例

1. Node.js with PostgreSQL

1. Node.js 搭配 PostgreSQL

javascript
// secure-db.js
const { Pool } = require('pg');

class SecureDatabase {
  constructor() {
    this.pool = new Pool({
      host: process.env.DB_HOST,
      database: process.env.DB_NAME,
      user: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      max: 20,
      idleTimeoutMillis: 30000,
      connectionTimeoutMillis: 2000
    });
  }

  /**
   * ✅ SECURE: Parameterized query
   */
  async getUserById(userId) {
    const query = 'SELECT * FROM users WHERE id = $1';
    const values = [userId];

    try {
      const result = await this.pool.query(query, values);
      return result.rows[0];
    } catch (error) {
      console.error('Query error:', error);
      throw error;
    }
  }

  /**
   * ✅ SECURE: Multiple parameters
   */
  async searchUsers(email, status) {
    const query = `
      SELECT id, email, name, created_at
      FROM users
      WHERE email LIKE $1 AND status = $2
      LIMIT 100
    `;
    const values = [`%${email}%`, status];

    const result = await this.pool.query(query, values);
    return result.rows;
  }

  /**
   * ✅ SECURE: Dynamic column ordering with whitelist
   */
  async getUsers(sortBy = 'created_at', order = 'DESC') {
    // Whitelist allowed columns
    const allowedColumns = ['id', 'email', 'name', 'created_at'];
    const allowedOrders = ['ASC', 'DESC'];

    if (!allowedColumns.includes(sortBy)) {
      sortBy = 'created_at';
    }

    if (!allowedOrders.includes(order.toUpperCase())) {
      order = 'DESC';
    }

    // Safe to use in query since values are whitelisted
    const query = `
      SELECT id, email, name, created_at
      FROM users
      ORDER BY ${sortBy} ${order}
      LIMIT 100
    `;

    const result = await this.pool.query(query);
    return result.rows;
  }

  /**
   * ✅ SECURE: Batch insert with prepared statement
   */
  async insertUsers(users) {
    const query = `
      INSERT INTO users (email, name, password_hash)
      VALUES ($1, $2, $3)
      RETURNING id
    `;

    const results = [];

    for (const user of users) {
      const values = [user.email, user.name, user.passwordHash];
      const result = await this.pool.query(query, values);
      results.push(result.rows[0].id);
    }

    return results;
  }

  /**
   * ✅ SECURE: Transaction with prepared statements
   */
  async transferFunds(fromAccount, toAccount, amount) {
    const client = await this.pool.connect();

    try {
      await client.query('BEGIN');

      // Debit from account
      await client.query(
        'UPDATE accounts SET balance = balance - $1 WHERE id = $2',
        [amount, fromAccount]
      );

      // Credit to account
      await client.query(
        'UPDATE accounts SET balance = balance + $1 WHERE id = $2',
        [amount, toAccount]
      );

      // Record transaction
      await client.query(
        'INSERT INTO transactions (from_account, to_account, amount) VALUES ($1, $2, $3)',
        [fromAccount, toAccount, amount]
      );

      await client.query('COMMIT');
      return true;
    } catch (error) {
      await client.query('ROLLBACK');
      throw error;
    } finally {
      client.release();
    }
  }

  /**
   * ❌ VULNERABLE: String concatenation (DON'T USE)
   */
  async vulnerableQuery(userId) {
    // VULNERABLE TO SQL INJECTION!
    const query = `SELECT * FROM users WHERE id = '${userId}'`;
    // Attack: userId = "1' OR '1'='1"
    // Result: SELECT * FROM users WHERE id = '1' OR '1'='1'

    const result = await this.pool.query(query);
    return result.rows;
  }
}

module.exports = SecureDatabase;
javascript
// secure-db.js
const { Pool } = require('pg');

class SecureDatabase {
  constructor() {
    this.pool = new Pool({
      host: process.env.DB_HOST,
      database: process.env.DB_NAME,
      user: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      max: 20,
      idleTimeoutMillis: 30000,
      connectionTimeoutMillis: 2000
    });
  }

  /**
   * ✅ 安全:参数化查询
   */
  async getUserById(userId) {
    const query = 'SELECT * FROM users WHERE id = $1';
    const values = [userId];

    try {
      const result = await this.pool.query(query, values);
      return result.rows[0];
    } catch (error) {
      console.error('Query error:', error);
      throw error;
    }
  }

  /**
   * ✅ 安全:多参数
   */
  async searchUsers(email, status) {
    const query = `
      SELECT id, email, name, created_at
      FROM users
      WHERE email LIKE $1 AND status = $2
      LIMIT 100
    `;
    const values = [`%${email}%`, status];

    const result = await this.pool.query(query, values);
    return result.rows;
  }

  /**
   * ✅ 安全:带白名单的动态列排序
   */
  async getUsers(sortBy = 'created_at', order = 'DESC') {
    // 白名单允许的列
    const allowedColumns = ['id', 'email', 'name', 'created_at'];
    const allowedOrders = ['ASC', 'DESC'];

    if (!allowedColumns.includes(sortBy)) {
      sortBy = 'created_at';
    }

    if (!allowedOrders.includes(order.toUpperCase())) {
      order = 'DESC';
    }

    // 由于值在白名单内,可安全用于查询
    const query = `
      SELECT id, email, name, created_at
      FROM users
      ORDER BY ${sortBy} ${order}
      LIMIT 100
    `;

    const result = await this.pool.query(query);
    return result.rows;
  }

  /**
   * ✅ 安全:使用预编译语句批量插入
   */
  async insertUsers(users) {
    const query = `
      INSERT INTO users (email, name, password_hash)
      VALUES ($1, $2, $3)
      RETURNING id
    `;

    const results = [];

    for (const user of users) {
      const values = [user.email, user.name, user.passwordHash];
      const result = await this.pool.query(query, values);
      results.push(result.rows[0].id);
    }

    return results;
  }

  /**
   * ✅ 安全:带预编译语句的事务
   */
  async transferFunds(fromAccount, toAccount, amount) {
    const client = await this.pool.connect();

    try {
      await client.query('BEGIN');

      // 从账户扣款
      await client.query(
        'UPDATE accounts SET balance = balance - $1 WHERE id = $2',
        [amount, fromAccount]
      );

      // 向账户存款
      await client.query(
        'UPDATE accounts SET balance = balance + $1 WHERE id = $2',
        [amount, toAccount]
      );

      // 记录交易
      await client.query(
        'INSERT INTO transactions (from_account, to_account, amount) VALUES ($1, $2, $3)',
        [fromAccount, toAccount, amount]
      );

      await client.query('COMMIT');
      return true;
    } catch (error) {
      await client.query('ROLLBACK');
      throw error;
    } finally {
      client.release();
    }
  }

  /**
   * ❌ 存在漏洞:字符串拼接(请勿使用)
   */
  async vulnerableQuery(userId) {
    // 易受SQL注入攻击!
    const query = `SELECT * FROM users WHERE id = '${userId}'`;
    // 攻击示例:userId = "1' OR '1'='1"
    // 结果:SELECT * FROM users WHERE id = '1' OR '1'='1'

    const result = await this.pool.query(query);
    return result.rows;
  }
}

module.exports = SecureDatabase;

2. Python with SQLAlchemy ORM

2. Python 搭配 SQLAlchemy ORM

python
undefined
python
undefined

secure_queries.py

secure_queries.py

from sqlalchemy import create_engine, Column, Integer, String, DateTime from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from datetime import datetime import re
Base = declarative_base()
class User(Base): tablename = 'users'
id = Column(Integer, primary_key=True)
email = Column(String(255), unique=True, nullable=False)
name = Column(String(100))
password_hash = Column(String(255))
created_at = Column(DateTime, default=datetime.utcnow)
class SecureDatabase: def init(self, connection_string): self.engine = create_engine(connection_string, pool_pre_ping=True) Base.metadata.create_all(self.engine) Session = sessionmaker(bind=self.engine) self.session = Session()
def get_user_by_id(self, user_id: int):
    """✅ SECURE: ORM query"""
    return self.session.query(User).filter(User.id == user_id).first()

def search_users(self, email: str):
    """✅ SECURE: Parameterized LIKE query"""
    return self.session.query(User).filter(
        User.email.like(f'%{email}%')
    ).limit(100).all()

def get_users_sorted(self, sort_by: str = 'created_at', order: str = 'desc'):
    """✅ SECURE: Whitelisted column sorting"""
    allowed_columns = {
        'id': User.id,
        'email': User.email,
        'name': User.name,
        'created_at': User.created_at
    }

    if sort_by not in allowed_columns:
        sort_by = 'created_at'

    column = allowed_columns[sort_by]

    if order.lower() == 'asc':
        column = column.asc()
    else:
        column = column.desc()

    return self.session.query(User).order_by(column).limit(100).all()

def raw_query_secure(self, user_id: int):
    """✅ SECURE: Raw SQL with parameters"""
    from sqlalchemy import text

    query = text("SELECT * FROM users WHERE id = :id")
    result = self.session.execute(query, {'id': user_id})

    return result.fetchall()

def validate_and_sanitize(self, input_str: str) -> str:
    """Validate and sanitize user input"""
    # Remove potentially dangerous characters
    # Only allow alphanumeric, spaces, and common punctuation
    sanitized = re.sub(r'[^\w\s@.,\-]', '', input_str)

    # Limit length
    sanitized = sanitized[:255]

    return sanitized

def vulnerable_query(self, user_input: str):
    """❌ VULNERABLE: String formatting (DON'T USE)"""
    from sqlalchemy import text

    # VULNERABLE TO SQL INJECTION!
    query = text(f"SELECT * FROM users WHERE email = '{user_input}'")
    # Attack: user_input = "' OR '1'='1"

    result = self.session.execute(query)
    return result.fetchall()
from sqlalchemy import create_engine, Column, Integer, String, DateTime from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from datetime import datetime import re
Base = declarative_base()
class User(Base): tablename = 'users'
id = Column(Integer, primary_key=True)
email = Column(String(255), unique=True, nullable=False)
name = Column(String(100))
password_hash = Column(String(255))
created_at = Column(DateTime, default=datetime.utcnow)
class SecureDatabase: def init(self, connection_string): self.engine = create_engine(connection_string, pool_pre_ping=True) Base.metadata.create_all(self.engine) Session = sessionmaker(bind=self.engine) self.session = Session()
def get_user_by_id(self, user_id: int):
    """✅ 安全:ORM查询"""
    return self.session.query(User).filter(User.id == user_id).first()

def search_users(self, email: str):
    """✅ 安全:参数化LIKE查询"""
    return self.session.query(User).filter(
        User.email.like(f'%{email}%')
    ).limit(100).all()

def get_users_sorted(self, sort_by: str = 'created_at', order: str = 'desc'):
    """✅ 安全:白名单列排序"""
    allowed_columns = {
        'id': User.id,
        'email': User.email,
        'name': User.name,
        'created_at': User.created_at
    }

    if sort_by not in allowed_columns:
        sort_by = 'created_at'

    column = allowed_columns[sort_by]

    if order.lower() == 'asc':
        column = column.asc()
    else:
        column = column.desc()

    return self.session.query(User).order_by(column).limit(100).all()

def raw_query_secure(self, user_id: int):
    """✅ 安全:带参数的原生SQL"""
    from sqlalchemy import text

    query = text("SELECT * FROM users WHERE id = :id")
    result = self.session.execute(query, {'id': user_id})

    return result.fetchall()

def validate_and_sanitize(self, input_str: str) -> str:
    """验证并清理用户输入"""
    # 移除潜在危险字符
    # 仅允许字母数字、空格和常见标点
    sanitized = re.sub(r'[^\w\s@.,\-]', '', input_str)

    # 限制长度
    sanitized = sanitized[:255]

    return sanitized

def vulnerable_query(self, user_input: str):
    """❌ 存在漏洞:字符串格式化(请勿使用)"""
    from sqlalchemy import text

    # 易受SQL注入攻击!
    query = text(f"SELECT * FROM users WHERE email = '{user_input}'")
    # 攻击示例:user_input = "' OR '1'='1"

    result = self.session.execute(query)
    return result.fetchall()

Usage

使用示例

if name == 'main': db = SecureDatabase('postgresql://user:pass@localhost/mydb')
# Secure queries
user = db.get_user_by_id(123)
users = db.search_users('example.com')
sorted_users = db.get_users_sorted('email', 'asc')
undefined
if name == 'main': db = SecureDatabase('postgresql://user:pass@localhost/mydb')
# 安全查询
user = db.get_user_by_id(123)
users = db.search_users('example.com')
sorted_users = db.get_users_sorted('email', 'asc')
undefined

3. Java JDBC with Prepared Statements

3. Java JDBC 搭配预编译语句

java
// SecureDatabase.java
package com.example.security;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class SecureDatabase {
    private Connection connection;

    public SecureDatabase(String url, String username, String password)
            throws SQLException {
        this.connection = DriverManager.getConnection(url, username, password);
    }

    /**
     * ✅ SECURE: Prepared statement
     */
    public User getUserById(int userId) throws SQLException {
        String sql = "SELECT * FROM users WHERE id = ?";

        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setInt(1, userId);

            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    return new User(
                        rs.getInt("id"),
                        rs.getString("email"),
                        rs.getString("name")
                    );
                }
            }
        }

        return null;
    }

    /**
     * ✅ SECURE: Multiple parameters
     */
    public List<User> searchUsers(String email, String status)
            throws SQLException {
        String sql = "SELECT * FROM users WHERE email LIKE ? AND status = ? LIMIT 100";

        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setString(1, "%" + email + "%");
            stmt.setString(2, status);

            try (ResultSet rs = stmt.executeQuery()) {
                List<User> users = new ArrayList<>();

                while (rs.next()) {
                    users.add(new User(
                        rs.getInt("id"),
                        rs.getString("email"),
                        rs.getString("name")
                    ));
                }

                return users;
            }
        }
    }

    /**
     * ✅ SECURE: Batch insert
     */
    public void insertUsers(List<User> users) throws SQLException {
        String sql = "INSERT INTO users (email, name, password_hash) VALUES (?, ?, ?)";

        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            for (User user : users) {
                stmt.setString(1, user.getEmail());
                stmt.setString(2, user.getName());
                stmt.setString(3, user.getPasswordHash());
                stmt.addBatch();
            }

            stmt.executeBatch();
        }
    }

    /**
     * ✅ SECURE: Dynamic sorting with whitelist
     */
    public List<User> getUsersSorted(String sortBy, String order)
            throws SQLException {
        // Whitelist allowed values
        List<String> allowedColumns = List.of("id", "email", "name", "created_at");
        List<String> allowedOrders = List.of("ASC", "DESC");

        if (!allowedColumns.contains(sortBy)) {
            sortBy = "created_at";
        }

        if (!allowedOrders.contains(order.toUpperCase())) {
            order = "DESC";
        }

        // Safe to use in query since values are whitelisted
        String sql = String.format(
            "SELECT * FROM users ORDER BY %s %s LIMIT 100",
            sortBy, order
        );

        try (Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {

            List<User> users = new ArrayList<>();

            while (rs.next()) {
                users.add(new User(
                    rs.getInt("id"),
                    rs.getString("email"),
                    rs.getString("name")
                ));
            }

            return users;
        }
    }

    /**
     * ❌ VULNERABLE: String concatenation (DON'T USE)
     */
    public List<User> vulnerableQuery(String userInput) throws SQLException {
        // VULNERABLE TO SQL INJECTION!
        String sql = "SELECT * FROM users WHERE email = '" + userInput + "'";
        // Attack: userInput = "' OR '1'='1"

        try (Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {

            List<User> users = new ArrayList<>();

            while (rs.next()) {
                users.add(new User(
                    rs.getInt("id"),
                    rs.getString("email"),
                    rs.getString("name")
                ));
            }

            return users;
        }
    }
}

class User {
    private int id;
    private String email;
    private String name;
    private String passwordHash;

    public User(int id, String email, String name) {
        this.id = id;
        this.email = email;
        this.name = name;
    }

    // Getters and setters
    public String getEmail() { return email; }
    public String getName() { return name; }
    public String getPasswordHash() { return passwordHash; }
}
java
// SecureDatabase.java
package com.example.security;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class SecureDatabase {
    private Connection connection;

    public SecureDatabase(String url, String username, String password)
            throws SQLException {
        this.connection = DriverManager.getConnection(url, username, password);
    }

    /**
     * ✅ 安全:预编译语句
     */
    public User getUserById(int userId) throws SQLException {
        String sql = "SELECT * FROM users WHERE id = ?";

        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setInt(1, userId);

            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    return new User(
                        rs.getInt("id"),
                        rs.getString("email"),
                        rs.getString("name")
                    );
                }
            }
        }

        return null;
    }

    /**
     * ✅ 安全:多参数
     */
    public List<User> searchUsers(String email, String status)
            throws SQLException {
        String sql = "SELECT * FROM users WHERE email LIKE ? AND status = ? LIMIT 100";

        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setString(1, "%" + email + "%");
            stmt.setString(2, status);

            try (ResultSet rs = stmt.executeQuery()) {
                List<User> users = new ArrayList<>();

                while (rs.next()) {
                    users.add(new User(
                        rs.getInt("id"),
                        rs.getString("email"),
                        rs.getString("name")
                    ));
                }

                return users;
            }
        }
    }

    /**
     * ✅ 安全:批量插入
     */
    public void insertUsers(List<User> users) throws SQLException {
        String sql = "INSERT INTO users (email, name, password_hash) VALUES (?, ?, ?)";

        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            for (User user : users) {
                stmt.setString(1, user.getEmail());
                stmt.setString(2, user.getName());
                stmt.setString(3, user.getPasswordHash());
                stmt.addBatch();
            }

            stmt.executeBatch();
        }
    }

    /**
     * ✅ 安全:带白名单的动态排序
     */
    public List<User> getUsersSorted(String sortBy, String order)
            throws SQLException {
        // 白名单允许的值
        List<String> allowedColumns = List.of("id", "email", "name", "created_at");
        List<String> allowedOrders = List.of("ASC", "DESC");

        if (!allowedColumns.contains(sortBy)) {
            sortBy = "created_at";
        }

        if (!allowedOrders.contains(order.toUpperCase())) {
            order = "DESC";
        }

        // 由于值在白名单内,可安全用于查询
        String sql = String.format(
            "SELECT * FROM users ORDER BY %s %s LIMIT 100",
            sortBy, order
        );

        try (Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {

            List<User> users = new ArrayList<>();

            while (rs.next()) {
                users.add(new User(
                    rs.getInt("id"),
                    rs.getString("email"),
                    rs.getString("name")
                ));
            }

            return users;
        }
    }

    /**
     * ❌ 存在漏洞:字符串拼接(请勿使用)
     */
    public List<User> vulnerableQuery(String userInput) throws SQLException {
        // 易受SQL注入攻击!
        String sql = "SELECT * FROM users WHERE email = '" + userInput + "'";
        // 攻击示例:userInput = "' OR '1'='1"

        try (Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {

            List<User> users = new ArrayList<>();

            while (rs.next()) {
                users.add(new User(
                    rs.getInt("id"),
                    rs.getString("email"),
                    rs.getString("name")
                ));
            }

            return users;
        }
    }
}

class User {
    private int id;
    private String email;
    private String name;
    private String passwordHash;

    public User(int id, String email, String name) {
        this.id = id;
        this.email = email;
        this.name = name;
    }

    // Getter和Setter方法
    public String getEmail() { return email; }
    public String getName() { return name; }
    public String getPasswordHash() { return passwordHash; }
}

4. Input Validation & Sanitization

4. 输入验证与清理

javascript
// input-validator.js
class InputValidator {
  static validateEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email) && email.length <= 255;
  }

  static validateInteger(value) {
    const num = parseInt(value, 10);
    return Number.isInteger(num) && num >= 0;
  }

  static sanitizeString(input, maxLength = 255) {
    // Remove control characters
    let sanitized = input.replace(/[\x00-\x1F\x7F]/g, '');

    // Trim and limit length
    sanitized = sanitized.trim().substring(0, maxLength);

    return sanitized;
  }

  static validateSQLIdentifier(identifier) {
    // Only allow alphanumeric and underscore
    return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(identifier);
  }

  static escapeForLike(input) {
    // Escape LIKE wildcards
    return input.replace(/[%_]/g, '\\$&');
  }
}

module.exports = InputValidator;
javascript
// input-validator.js
class InputValidator {
  static validateEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email) && email.length <= 255;
  }

  static validateInteger(value) {
    const num = parseInt(value, 10);
    return Number.isInteger(num) && num >= 0;
  }

  static sanitizeString(input, maxLength = 255) {
    // 移除控制字符
    let sanitized = input.replace(/[\x00-\x1F\x7F]/g, '');

    // 去除首尾空格并限制长度
    sanitized = sanitized.trim().substring(0, maxLength);

    return sanitized;
  }

  static validateSQLIdentifier(identifier) {
    // 仅允许字母数字和下划线
    return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(identifier);
  }

  static escapeForLike(input) {
    // 转义LIKE通配符
    return input.replace(/[%_]/g, '\\$&');
  }
}

module.exports = InputValidator;

Best Practices

最佳实践

✅ DO

✅ 建议

  • Use prepared statements ALWAYS
  • Use ORM frameworks properly
  • Validate all user inputs
  • Whitelist dynamic values
  • Use least privilege DB accounts
  • Enable query logging
  • Regular security audits
  • Use parameterized queries
  • 始终使用预编译语句
  • 正确使用ORM框架
  • 验证所有用户输入
  • 对白名单动态值
  • 使用权限最小化的数据库账户
  • 启用查询日志
  • 定期进行安全审计
  • 使用参数化查询

❌ DON'T

❌ 禁止

  • Concatenate user input
  • Trust client-side validation
  • Use string formatting for queries
  • Allow dynamic table/column names
  • Grant excessive DB permissions
  • Skip input validation
  • 拼接用户输入
  • 信任客户端验证
  • 使用字符串格式化生成查询
  • 允许动态表/列名
  • 授予过多数据库权限
  • 跳过输入验证

Prevention Techniques

防护技术

  1. Prepared Statements: Parameterized queries
  2. ORM Frameworks: Abstraction layer
  3. Input Validation: Whitelist approach
  4. Least Privilege: Minimal DB permissions
  5. WAF: Web Application Firewall
  6. Code Review: Manual inspection
  1. 预编译语句:参数化查询
  2. ORM框架:抽象层
  3. 输入验证:白名单方式
  4. 最小权限:最小数据库权限
  5. WAF:Web应用防火墙
  6. 代码审查:人工检查

Testing for SQL Injection

SQL注入测试

  • Manual testing: Input payloads
  • Automated scanners: SQLMap, Burp Suite
  • Code review: Static analysis
  • Penetration testing: Professional assessment
  • 手动测试:输入攻击载荷
  • 自动化扫描工具:SQLMap、Burp Suite
  • 代码审查:静态分析
  • 渗透测试:专业评估

Resources

参考资源