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

SQL 注入與防禦實戰:MySQL 中 HAVING 1=1 技巧失效分析

     編輯:MySQL 綜合教學

SQL 注入與防禦實戰:MySQL 中 HAVING 1=1 技巧失效分析

某安全書籍介紹利用 HAVING 1=1 觸發錯誤回顯獲取資訊,但在 MySQL 5.1.66 實測中該技巧失效。本文分析原因,並探討 MySQL 中構造必報錯語句的函數組合。

一、書籍所述技巧

-- SQL Server 環境
SELECT * FROM table WHERE id=2 HAVING 1=1;
-- 報錯:缺少 GROUP BY,錯誤訊息可能洩露結構資訊

二、 MySQL 實測結果

mysql> SELECT * FROM aa WHERE id=2 HAVING 1=1;
+----+------+
| id | name |
+----+------+
|  2 | test |
+----+------+
1 row in set (0.00 sec)
-- 正常返回結果,無報錯

三、差異根因

MySQL 允許 HAVING 無 GROUP BY,將整個結果集視為一組進行過濾,語義等同 WHERE。

四、MySQL 中構造必報錯語句的函數組合

要觸發 MySQL 語法/運行時錯誤,需利用「強制同時存在」的語法結構:

  1. 聚合函數與非聚合列混用且無 GROUP BY:
    SELECT id, COUNT(*) FROM aa;  -- ERROR 1140: Mixing of GROUP columns
  2. 子查詢返回多行用於單值上下文:
    SELECT * FROM aa WHERE id = (SELECT id FROM aa);  -- ERROR 1242: Subquery returns more than 1 row
  3. 類型轉換失敗:
    SELECT 'abc' + 1;  -- 警告 Truncated, 不報錯
    SELECT CAST('abc' AS UNSIGNED); -- 返回 0, 不報錯
    
  4. 除零錯誤 (需 sql_mode):
    SET SESSION sql_mode='ERROR_FOR_DIVISION_BY_ZERO';
    SELECT 1/0;  -- ERROR 1365: Division by 0
  5. 函數參數類型/數量錯誤:
    SELECT DATE_FORMAT(NOW());  -- ERROR 1582: Incorrect parameter count

五、防禦體系建設 (重點)

  1. 參數化查詢 / 預處理語句:根治注入,PreparedStatement、PDO::prepare
  2. 最小權限帳號:應用帳號僅擁有必要增刪改查權限,無 DDL/DCL 權限
  3. 錯誤訊息不回顯給前端:生產環境關閉 display_errors,統一友好提示
  4. WAF/IDS:ModSecurity + OWASP CRS 規則集攔截常見攻擊載荷
  5. 審計日誌:MariaDB Audit Plugin / MySQL Enterprise Audit 記錄所有 DML/DDL
  6. 定期掃描:sqlmap、OWASP ZAP 自動化掃描驗證防禦有效性

六、總結

不同資料庫對 SQL 標準的實現細節差異巨大,攻擊技巧極強相關性。防禦不應依賴「攻擊失效」,而應建立「參數化查詢 + 最小權限 + 錯誤隱藏 + 審計監控」的纵深防禦體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性SQL ServerMySQL
HAVING 無 GROUP BY語法錯誤,拋出異常合法,視為全表單一分組,等同 WHERE
錯誤回顯可利用獲取元數據此處不產生錯誤