带有 DBMS_ASSERT 的 Oracle SQL 注入块

shi*_*i92 3 oracle plsql

此代码触发错误

  query_string := 'SELECT '||dbms_assert.sql_object_name(trim(both ' ' from return_field))|| 
                   ' FROM '||dbms_assert.schema_name(trim(both ' ' from_schema))||
                        '.'||dbms_assert.sql_object_name(trim(''' from_table))||  
                  ' WHERE '||dbms_assert.sql_object_name(key_field) || ' = '||key_value;



 EXECUTE IMMEDIATE query_string into return_result;

无效的 sql 对象。

从文档中我觉得表中的任何对象都是 sql 对象?
怎么了?

考虑 oracle 10g 中的以下功能

在 10g 上下文中考虑以下函数

    创建或替换功能 scott.tab_lookup (key_field CHAR,
                                       键值字符,
                                       from_schema CHAR,
                                       from_table CHAR,
                                       返回字段字符,
                                       return_type CHAR)
    返回 VARCHAR2 是
    result_a varchar2(1000);
    查询字符串 VARCHAR2(4000);

    /*版本0.5*/
    开始

    query_string := 'SELECT '||dbms_assert.qualified_sql_name(trim(from_table||'.'||return_field))|| 
                       ' FROM '||dbms_assert.schema_name(trim(from_schema))||
                            '.'||dbms_assert.sql_object_name(trim(from_table))||  
                      ' WHERE '||dbms_assert.qualified_sql_name(from_table||'.'||key_field) || ' = '||key_value;

      IF(return_type = 'SQL') THEN
         结果_a := query_string;
      别的
         立即执行 query_string 
         --使用键值  
         进入result_a;
      万一;

      返回 (result_a);
    例外 
    什么时候 
        NO_DATA_FOUND THEN 
           返回(空);
    什么时候
        TOO_MANY_ROWS THEN 
           RETURN('**ERR_DUPLICATE**');
    当别人
    然后 
    /*
    ORA-44001 INVALID_SCHEMA_NAME 
    ORA-44002 INVALID_OBJECT_NAME
    ORA-44003 INVALID_SQL_NAME
    ORA-44004 INVALID_QUALIFIED_SQL_NAME
    */
        如果 SQLCODE = -44001 那么 
              RETURN('*ERR_INVALID_SCHEMA*');
        ELSIF SQLCODE = -44002 THEN 
              RETURN('*ERR_INVALID_OBJECT*');
        ELSIF SQLCODE = -44003 THEN 
              RETURN('*ERR_INVALID_SQL_NAME*');
        ELSIF SQLCODE = -44004 THEN 
              RETURN('*ERR_INVALID_QALIFIED_SQLNAME*');
        万一;         
        return ('*ERR_'||sqlcode);
    结尾;
    /

我收到ERR_INVALID_OBJECT

-- 获取生成的 SQL 作为值  

    选择 scott.tab_lookup('ID',1,'TEST','TEST_TABLE','TEST_DESC','SQL') from dual;

-  -或者-

-- 获取从数据库字段返回的值

    选择 scott.tab_lookup('ID',1,'TEST','TEST_TABLE','TEST_DESC','') from dual;

我的桌子就像

    TEST_TABLE  
    ====================
    ID , TEST_DESC
    ====================
    '11' , '测试 1'
    '12', '测试 5000'
    '13' , '测试输入值'
    '14' , '垃圾值'
    '50' , '测试值 50'

该表在“TEST”模式中,我与 SCOTT 相连,SCOTT 对 TEST.TEST_TABLE 进行了“GRANT SELECT 到 scott”

我仍然收到错误

ERR_INVALID_OBJECT

Mah*_*kar 6

query_string := 'SELECT '||dbms_assert.qualified_sql_name(trim(from_schema||'.'||from_table||'.'||return_field))|| 
                   ' FROM '||dbms_assert.schema_name(trim(from_schema))||
                        '.'||dbms_assert.sql_object_name(trim(from_table))||  
                  ' WHERE '||dbms_assert.qualified_sql_name(from_schema||'.'||from_table||'.'||key_field) || ' = '||key_value;



 EXECUTE IMMEDIATE query_string into return_result;
Run Code Online (Sandbox Code Playgroud)

文档..

  • ENQUOTE_LITERAL - 引用字符串文字
  • ENQUOTE_NAME - 用双引号将名称括起来
  • NOOP - 不做任何检查就返回值
  • QUALIFIED_SQL_NAME - 验证输入字符串是否为限定的 SQL 名称
  • SCHEMA_NAME - 函数验证输入字符串是否为现有模式名称
  • SIMPLE_SQL_NAME - 验证输入字符串是一个简单的 SQL 名称
  • SQL_OBJECT_NAME - 验证输入参数字符串是现有 SQL 对象的限定 SQL 标识符