首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

SQL 注入原理與防範:Statement vs PreparedStatement 實測對比

     編輯:MySQL 綜合教學

SQL 注入原理與防範:Statement vs PreparedStatement 實測對比

經典 ' OR 1=1 -- 繞過登錄演示,對比 Statement(拼接 SQL)與 PreparedStatement(參數化查詢)對注入的防禦能力差異。

注入演示

原始查詢:

SELECT * FROM users WHERE username='input_user' AND password='input_pass'

惡意輸入:
username: admin
password: ' OR 1=1 -- (注意 -- 後有空格)

拼接後 SQL:

SELECT * FROM users WHERE username='admin' AND password='' OR 1=1 -- '

-- 註釋掉後續單引號,1=1 恆真,直接登入。

Statement vs PreparedStatement

維度StatementPreparedStatement
SQL 構建字符串拼接預編譯 + 參數佔位符 ?
上述注入✅ 成功繞過❌ 失敗(參數視為字面值)
性能每次解析編譯預編譯一次,多次複用計劃
類型安全無強類型綁定

PreparedStatement 防注入原理

// Java 範例
String sql = "SELECT * FROM users WHERE username=? AND password=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, username);  // 參數傳輸與 SQL 結構分離
ps.setString(2, password);
ResultSet rs = ps.executeQuery();

數據庫引擎在預編譯階段確定執行計劃,參數永遠不會改變 SQL 結構,徹底杜絕注入。

最佳實踐清單

  1. **全應用禁用 Statement**,強制 PreparedStatement/ORM 參數化
  2. 輸入驗證:白名單校驗、長度限制、特殊字符轉義(防禦深度)
  3. 最小權限:應用布號僅 SELECT/INSERT/UPDATE/DELETE,無 DROP/ALTER
  4. WAF/防火牆層面攔截疑似注入特徵
  5. 定期掃描:sqlmap、OWASP ZAP 自動化檢測

補充:MySQL 端防禦

  • sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER
  • 避免動態 SQL 構建(存儲過程中用 PREPARE/EXECUTE)
  • 審計日志:MariaDB Audit Plugin、MySQL Enterprise Audit
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved