Postgresql
Postgres 函式中的 SQL 注入與準備好的查詢
在 Postgres 中,準備好的查詢和使用者定義的函式是否等同於防止 SQL 注入的機制?
一種方法比另一種方法有什麼特別的優勢嗎?
這取決於。
SQL 函式
有了
LANGUAGE sql
,答案一般是肯定的。傳遞的參數被視為值,並且不可能進行 SQL 注入 - 只要您不從主體呼叫不安全的函式並傳遞參數。
PL/pgSQL 函式
有了
LANGUAGE plpgsql
,答案通常是肯定的。但是,PL/pgSQL 允許動態 SQL,其中傳遞的參數(或部分)連接到查詢字元串並使用**
EXECUTE
**. 這可以將使用者輸入轉換為 SQL 程式碼並使 SQL 注入成為可能。您無法從外部判斷函式體是否正確處理它。提供工具。僅在需要的地方使用動態 SQL。使用參數作為值的普通 SQL 語句對於 SQL 注入(如 SQL 函式)是安全的。
對於動態 SQL,最好將值作為值傳遞:
USING
條款。例子。原則上使 SQL 注入成為不可能。
如果連接SQL 字元串中的值,請使用:
安全地將字元串包裹在單引號中,從而避免語法錯誤和 SQL 注入。
應被視為SQL 字元串中的標識符的過程參數:
format()
帶格式說明符%I
。例子。quote_ident()
. 例子。- 轉換為已註冊類型-
regclass
對於表名:_tbl::regclass
. 例子。在需要的地方用雙引號將標識符字元串安全地括起來,從而避免語法錯誤和 SQL 注入。
有關的:
永遠不要僅僅從使用者輸入建構一個字元串並執行。這包括標識符,由使用者直接傳遞或從系統目錄中獲取。在建構動態 SQL 時,所有內容都必須被視為使用者輸入並適當引用!
有關此相關答案中性能影響的更多資訊:
SQL注入的基礎知識:
類似的考慮適用於其他允許動態 SQL的伺服器端語言。