<select id="findByName" resultType="User">
SELECT * FROM t_user WHERE name LIKE '%' || #{name} || '%'
</select>
生成 SQL:SELECT * FROM t_user WHERE name LIKE '%' || ? || '%'
JDBC 驅動將使用者輸入視為參數值,單引號等特殊字元自動轉義,徹底阻斷注入。
<select id="findByNameUnsafe" resultType="User">
SELECT * FROM t_user WHERE name LIKE '%' || ${name} || '%'
</select>
若使用者輸入 `test' OR '1'='1`,生成 SQL 變為:
SELECT * FROM t_user WHERE name LIKE '%' || 'test' OR '1'='1' || '%'
邏輯被竄改,返回所有使用者。
ORDER BY ${sortColumn} ${sortOrder}| 誤區 | 事實 |
|---|---|
| 「Oracle 不用擔心注入」 | 所有支援參數化查詢的資料庫皆需使用參數化;Oracle 同樣易受注入攻擊。 |
| 「#{ } 處理 LIKE 通配符麻煩」 | 在 Java 端組裝:`param = "%" + userInput + "%"`,再傳入 `#{param}`,兼具安全與便利。 |
| 「存儲過程呼叫不需參數化」 | `{call proc(#{param})}` 同樣需用 `#{}`,避免存儲過程內部動態 SQL 注入。 |