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

Oracle PL/SQL動態SQL注入防禦:DBMS_ASSERT包實戰應用指南

     編輯:Oracle 資料庫基礎

從Java層防禦延伸到資料庫層:PL/SQL動態SQL注入風險與修復方案

企業常重視應用層PreparedStatement防注入,卻忽略PL/SQL動態SQL(EXECUTE IMMEDIATE)同樣存在注入風險。本文透過實例演示攻擊向量與DBMS_ASSERT修復全過程。

一、脆弱程式碼範例


CREATE OR REPLACE PROCEDURE disable_constraint(
  p_constraint_name VARCHAR2,
  p_table           VARCHAR2
) AUTHID CURRENT_USER
AS
  p_schema  VARCHAR2(32) := USER;
  sql_stmt  VARCHAR2(2000) := 'ALTER TABLE ' || p_schema || '.' || p_table
                           || ' DISABLE CONSTRAINT ' || p_constraint_name;
BEGIN
  EXECUTE IMMEDIATE sql_stmt;
END;
/

二、三大注入向量分析

三、防禦策略優先序

  1. 靜態SQL:能不用動態SQL就不用
  2. 綁定變數:EXECUTE IMMEDIATE 'SELECT * FROM t WHERE id=:b' USING v_id; — 但DDL不支援綁定
  3. 輸入驗證/清洗:DBMS_ASSERT包 — DDL動態SQL唯一可行方案

四、DBMS_ASSERT核心函數評測

參數攻擊載荷範例造成影響
p_tablet1; DROP TABLE users; --執行任意DDL/DML
p_constraint_namec1; GRANT DBA TO PUBLIC; --權限提升
p_schema(USER)惡意建立名為"SCOTT; DROP TABLE t"的用戶間接注入

五、修復後程式碼


CREATE OR REPLACE PROCEDURE disable_constraint(
  p_constraint_name VARCHAR2,
  p_table           VARCHAR2
) AUTHID CURRENT_USER
AS
  p_schema       VARCHAR2(32) := SYS.DBMS_ASSERT.ENQUOTE_NAME(USER, FALSE);
  sql_stmt       VARCHAR2(2000);
  safe_table     VARCHAR2(32);
  safe_constraint VARCHAR2(32);
BEGIN
  safe_table      := SYS.DBMS_ASSERT.ENQUOTE_NAME(p_table, FALSE);
  safe_constraint := SYS.DBMS_ASSERT.ENQUOTE_NAME(p_constraint_name, FALSE);
  
  sql_stmt := 'ALTER TABLE ' || p_schema || '.' || safe_table
           || ' DISABLE CONSTRAINT ' || safe_constraint;
  
  EXECUTE IMMEDIATE sql_stmt;
END;
/

六、關鍵注意事項

  • 大小寫敏感:ENQUOTE_NAME(..., FALSE)保留原大小寫,呼叫端必須傳入正確大小寫(如Table_1而非TABLE_1)
  • AUTHID CURRENT_USER:以呼叫者權限執行,配合DBMS_ASSERT雙重防護
  • 審計追蹤:建立DDL觸發器記錄所有ALTER/DROP/GRANT操作
  • 程式碼掃描:納入CI/CD靜態分析,標記所有EXECUTE IMMEDIATE需人工審查

七、延伸防禦

  • 最小權限:程式單元擁有者僅具備必要DDL權限
  • 資料庫防火牆/統一審計:記錄所有動態SQL執行
  • 定期滲透測試:含PL/SQL注入測試案例
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數功能適用性評估
SIMPLE_SQL_NAME驗證簡單SQL名稱(無特殊字元)❌ 資料字典讀出的名稱不含雙引號,驗證失敗
QUALIFIED_SQL_NAME驗證完整限定名(schema.object)❌ 同左,雙引號問題
SCHEMA_NAME驗證現有Schema名稱⚠️ 二次攻擊風險:攻擊者預建惡意名稱物件
SQL_OBJECT_NAME驗證現有物件名稱⚠️ 同左,二次攻擊風險
ENQUOTE_NAME雙引號包裹名稱,驗證合法性✅ 最佳選擇:防注入+保留大小寫+無二次攻擊風險
ENQUOTE_LITERAL單引號包裹字面值適用字串字面值,非識別碼