ITPub博客

首页 > 数据库 > Oracle > 反恐精英之动态SQL和SQL注入-SQL注入-防卫SQL注入-验证检查

反恐精英之动态SQL和SQL注入-SQL注入-防卫SQL注入-验证检查

原创 Oracle 作者:luisedalian 时间:2014-02-16 11:24:11 0 删除 编辑

通常应用程序应该验证用户的输入,以确保输入的内容是所希望的。

例,如果用户为delete语句传入部门编号,可以从departments表中做查询来验证输入的部门编号;

如果用户输入删除的表名,则可以查询all_tables来验证表名的存在。

在有效性检查代码中,DBMS_ASSERT包中的子程序是有用的。

可以使用DBMS_ASSERT.ENQUOTE函数来将字符串字面量使用引号括起来。这可以阻止恶意用户在开始和结束引号间注入文本。

-- 11g12_07_13.prc

CREATE OR REPLACE PROCEDURE raise_emp_salary (column_value  NUMBER, emp_column VARCHAR2, amount NUMBER)

IS

    v_column  VARCHAR2(30);

    sql_stmt  VARCHAR2(200);

BEGIN

    -- 检测输入的列名有效性

    SELECT column_name INTO v_column FROM USER_TAB_COLS

    WHERE TABLE_NAME = 'EMPLOYEES' AND COLUMN_NAME = emp_column;

    sql_stmt := 'UPDATE employees SET salary = salary + :b1 WHERE '

    || DBMS_ASSERT.ENQUOTE_NAME(v_column, FALSE) || ' = :b2';

    EXECUTE IMMEDIATE sql_stmt USING amount, column_value;

    -- 如果列名有效

    IF SQL%ROWCOUNT > 0 THEN

        DBMS_OUTPUT.PUT_LINE('更新列: ' || emp_column || ' = ' || column_value || '的员工薪水');

    END IF;

    -- 如果列名无效

    EXCEPTION

        WHEN NO_DATA_FOUND THEN

            DBMS_OUTPUT.PUT_LINE ('无效列: ' || emp_column);

END raise_emp_salary;

--11g12_07_13.tst

--测试前先查看相关的数据

SELECT employee_id, department_id, salary FROM employees

WHERE employee_id = 112 OR department_id = 110;

DECLARE

    plsql_block  VARCHAR2(500);

BEGIN

  -- 从动态SQL块调用

    plsql_block :=

        'BEGIN raise_emp_salary(:cvalue, :cname, :amt); END;';

    EXECUTE IMMEDIATE plsql_block USING 110, 'DEPARTMENT_ID', 10;

  -- 从动态SQL语句调用

  --EXECUTE IMMEDIATE 'BEGIN raise_emp_salary(:cvalue, :cname, :amt); END;'

  --USING 112, 'EMPLOYEE_ID', 10;

END;

1次执行:

2次执行

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17013648/viewspace-1082050/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-02-06

  • 博文量
    1986
  • 访问量
    5641758