You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在DBMS_SQL.PARSE中用绑定变量防SQL注入?DDL场景咨询

技术指引:DDL动态SQL的SQL注入规避与Checkmarx告警处理

核心结论:DDL无法用绑定变量替代对象名

Oracle的绑定变量仅支持数据值的绑定(比如SELECT/WHERE子句中的条件值),对于DDL中的对象标识符(如用户名、表名、索引名等属于SQL语法结构的部分),无法通过绑定变量动态传入,因此直接用绑定变量解决DDL的字符串拼接问题不可行。

针对DDL动态SQL的安全方案

1. 白名单校验(最安全的方式)

DDL属于高风险操作,输入的对象名(如示例中的userid)应处于业务可控范围,先通过白名单验证确保输入合法:

  • 校验输入的userid是否存在于合法用户列表(比如查询DBA_USERS视图确认用户存在)
  • 或者从业务系统的用户管理表中验证该用户是允许被删除的对象

示例代码(加入白名单校验):

PROCEDURE drop_user_proc(p_userid IN VARCHAR2) IS
  v_exists NUMBER;
  v_sqlstatement VARCHAR2(1000);
  v_cursor INTEGER;
BEGIN
  -- 白名单校验:确认用户存在
  SELECT COUNT(1) INTO v_exists
  FROM DBA_USERS
  WHERE USERNAME = UPPER(p_userid);
  
  IF v_exists = 0 THEN
    RAISE_APPLICATION_ERROR(-20001, '用户不存在,无法执行删除操作');
  END IF;

  v_cursor := DBMS_SQL.open_cursor;
  v_sqlstatement := 'DROP USER ' || UPPER(p_userid);
  DBMS_SQL.parse(v_cursor, v_sqlstatement, DBMS_SQL.NATIVE);
  DBMS_SQL.close_cursor(v_cursor);
END;

2. 使用DBMS_ASSERT包做标识符安全校验

如果无法用白名单,必须允许动态对象名,使用Oracle官方提供的DBMS_ASSERT包校验输入的标识符,避免注入风险:

  • DBMS_ASSERT.SIMPLE_SQL_NAME:校验输入是否符合Oracle简单标识符规范
  • DBMS_ASSERT.ENQUOTE_NAME:将标识符转为带引号的合法形式(支持包含特殊字符的标识符)

示例代码(使用DBMS_ASSERT):

PROCEDURE drop_user_proc(p_userid IN VARCHAR2) IS
  v_safe_userid VARCHAR2(30);
  v_sqlstatement VARCHAR2(1000);
  v_cursor INTEGER;
BEGIN
  -- 校验并转义用户名,确保合法
  v_safe_userid := DBMS_ASSERT.SIMPLE_SQL_NAME(p_userid);
  
  v_cursor := DBMS_SQL.open_cursor;
  v_sqlstatement := 'DROP USER ' || v_safe_userid;
  DBMS_SQL.parse(v_cursor, v_sqlstatement, DBMS_SQL.NATIVE);
  DBMS_SQL.close_cursor(v_cursor);
END;

3. 简化动态SQL写法(替代DBMS_SQL)

对于简单的DDL操作,推荐使用EXECUTE IMMEDIATE替代DBMS_SQL,代码更简洁,同时配合上述安全校验:

PROCEDURE drop_user_proc(p_userid IN VARCHAR2) IS
  v_safe_userid VARCHAR2(30);
BEGIN
  v_safe_userid := DBMS_ASSERT.SIMPLE_SQL_NAME(p_userid);
  EXECUTE IMMEDIATE 'DROP USER ' || v_safe_userid;
END;

关于Checkmarx告警的处理

Checkmarx会基于“字符串拼接动态SQL”的规则触发告警,只要你实现了上述任意一种安全校验(白名单/DBMS_ASSERT),可以:

  • 向Checkmarx提交误报申诉,提供安全校验的代码说明
  • 调整Checkmarx的扫描规则,对包含DBMS_ASSERT或白名单校验的动态SQL放行

内容的提问来源于stack exchange,提问作者Deva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:42:37