本文匯總兩類「精妙」SQL:一類是解決實際業務問題的高效語句模式 (複製表、外部聯結、分組最新記錄、隨機抽樣、刪除關聯孤兒資料);另一類從安全角度剖析 SQL 注入中結果集差異 (邏輯/語法/執行錯誤) 的利用原理,助開發者理解防禦本質。
| 場景 | SQL 模式 |
|---|---|
| 複製表結構 | SELECT * INTO b FROM a WHERE 1<>1; |
| 複製表資料 | INSERT INTO b (c1,c2,c3) SELECT d,e,f FROM a; |
| 顯示文章/作者/最新回覆 | SELECT a.title, a.username, b.adddate FROM a, (SELECT MAX(adddate) adddate FROM a GROUP BY title) b; |
| 外部聯結查詢 | SELECT a.a, a.b, a.c, b.c, b.d, b.f FROM a LEFT OUT JOIN b ON a.a = b.c; |
| 排程提前 5 分鐘提醒 | SELECT * FROM schedule WHERE DATEDIFF(minute, start_time, GETDATE()) > 5; |
| 刪除主表中副表無對應資料 | DELETE FROM info WHERE NOT EXISTS (SELECT 1 FROM infobz WHERE info.infid = infobz.infid); |
| 複雜庫存對帳 (Oracle 語法) | 多層子查詢 + TO_CHAR 日期截取 + NVL 空值處理 + 外部聯結 (+),對比月度入庫/庫存變動。 |
| 學生資料篩選 (動態 WHERE) | SELECT * FROM studentinfo WHERE NOT EXISTS (SELECT 1 FROM student WHERE studentinfo.id=student.id) AND dept=@dept AND major=@major ORDER BY gender, origin, score DESC; |
SELECT * FROM news WHERE id=1 AND 1=2 → 結果集為空 → 應用層無資料顯示/跳轉。
SELECT * FROM news WHERE id=1 OR 1=1 → 結果集暴增 → 若應用取第一筆 → 可能非預期記錄 → 頁面內容異常。
本質: WHERE 條件真假導致結果集基數變化,引發應用層邏輯分支差異。
構造語法錯誤 (如型別轉換失敗、函數參數錯誤) 觸發資料庫拋出錯誤訊息。若應用未屏蔽錯誤 → 錯誤訊息回顯於頁面 (含資料庫版本、表結構、資料內容)。
利用: `CAST((SELECT TOP 1 name FROM sysobjects) AS INT)` 強制轉換失敗,錯誤訊息攜帶表名。Oracle/PostgreSQL 空結果集常顯示 `NULL` 字串,亦為特徵。
MySQL `BENCHMARK(1000000, MD5('x'))`、SQL Server `WAITFOR DELAY '0:0:5'` 造成執行緒阻塞。頁面回應延遲 → 推斷條件真假。適用於無回顯、無錯誤訊息的盲注場景。
利用 `IFF(1=1, 1, 'no')` 返回數字,`IFF(1=2, 1, 'no')` 返回字串。
id=1 AND 1=IFF(1=1,1,'no') 成功 (數字=數字);
id=1 AND 1=IFF(1=2,1,'no') 失敗 (數字=字串 → 型別轉換錯誤)。
透過「成功/報錯」二元特徵提取位資訊。支援 IFF/CASE/DECODE 的資料庫適用。