SQL注入是一个老的安全问题,哪里有SQL,哪里就有SQL注入。一般的企业应用只关注java级别的编写规范,比如使用preparedStatement,或者简单的过滤掉危险字符等等。
其实写PL/SQL函数或者过程的时候,也有注入的问题。简单讨论一下吧。
例如,有一个过程具有禁用表约束的功能:
Sql代码
创建或替换过程Disable _ Constraint(p _ Constraint _ name varchar 2,p_table VARCHAR2)
AUTHID当前用户
如同
p _ schema varchar 2(32):= USER;
sql_stmt VARCHAR2(2000) := '更改表'
|| p_schema
|| '.'
|| p_table
|| '禁用约束'
| | p _ constraint _ name
开始
立即执行sql _ stmt
结束;
/
了解SQL注入的学生应该能够看出在上述过程中有几个危险的变量:
1.p _表格
2.p _约束_名称
3.p _模式
前两个很好找,但是为什么会有p_schema?因为当前用户名也可能是用户构造的危险字符串。好的,根据一般规则,我们应该按照以下顺序进行修改:
1.静态SQL。如果不能使用变量,就不要使用。
2.绑定变量。类似于Java中的PreparedStatement,数据在sql中不是直接拼接的,而是存储在变量中,由数据库直接使用。
3.检查变量的值。
显然,前两种方法不适用于这一程序。我们只能用第三种方法,这是最不愉快的。幸运的是,对于PL/SQL,我们不必自己编写复杂的字符判断。甲骨文有一个系统。DBMS_ASSERT包,它提供了一些预置功能,如下:
不操作。返回未更改的字符串
SIMPLE_SQL_NAME验证输入字符串是简单的SQL名称。
QUALIFIED_SQL_NAME验证输入字符串是合格的SQL名称。
SCHEMA_NAME该函数验证输入字符串是否是现有的模式名。
SQL_OBJECT_NAME此函数验证输入参数字符串是否是现有SQL对象的合格SQL标识符。
ENQUOTE_NAME该函数用双引号将名称括起来。
向字符串文字添加前导和尾随单引号。
(请参考:http://download.oracle.com/docs/cd/b28359 _ 01/app dev . 111/b 28419/d _ assert.htm)
当执行这些函数时,如果传递的变量不符合规定的格式或条件,就会抛出异常,从而保护我们自己的过程不被SQL注入。
我们判断这些方法是否可用:
1.简单SQL名称,限定SQL名称
这些方法要求用户自己输入和退出的参数是有效的sql名称。例如,如果有一个名为“Table One & quot,则传入的值需要包含双引号。使用这些方法有一个问题,即直接从data-dictionary中读取的表名没有双引号。如果用户直接从数据字典中读取表名,然后直接将其传递给我们的过程,将会抛出一个异常,因为它不符合简单sql name的要求,但实际上这个表名应该是正确的。因此,这些函数不能直接使用。
2.架构名称,SQL对象名称
这些方法要求传入的参数值是数据库中已经存在的对象的名称。如果数据库中有一个名为“表一”的表,那么如果用户传入表一,就认为是正确的。通过这些方法,可以避免第一种方法的数据字典问题,也可以避免类似table' -的问题。但是存在所谓二次攻击的问题。如果用户预先创建一个包含危险字符的表,然后调用我们的过程,仍然会导致SQL注入。
3.询问名称,询问文字
这些方法直接用双引号或单引号将参数值括起来。如果包含的值本身仍然是危险的,将会抛出一个异常。对于我们的示例过程,我们只需要使用ENQUOTE_NAME。ENQUOTE_NAME需要两个参数,一个是需要ENQUOTE的变量,一个是是否转换成大写。现在,对于我们的过程,应该使用ENQUOTE_NAME(p_table,FALSE)来确保表一不会转换为“表一”。
这是我们的最终解决方案。但是应该注意,由于使用了ENQUOTE_NAME,对于我们的过程,表和约束的名称是区分大小写的。如果名称是table_1,则必须传入TABLE_1,否则将执行错误。
修改后的代码如下:
Sql代码
创建或替换过程Disable _ Constraint(p _ Constraint _ name varchar 2,p_table VARCHAR2)
AUTHID当前用户
如同
p_schema VARCHAR2(32) := SYS。DBMS_ASSERT。ENQUOTE_NAME(USER,FALSE);
SQL _ stmt varchar 2(2000);
safe _ table varchar 2(32);
safe _ constraint varchar 2(32);
开始
安全_表:=系统。DBMS_ASSERT。ENQUOTE_NAME(p_table,FALSE);
安全约束:=系统。DBMS_ASSERT。ENQUOTE_NAME(p_constraint_name,FALSE);
sql_stmt := 'ALTER TABLE '
|| p_schema
|| '.'
||安全_表格
|| '禁用约束'
| | safe _ constraint
立即执行sql _ stmt
结束;
/
关键词:SQL注入,甲骨文数据库
优侠库网站每天提供最新最热门的安卓手机软件、游戏下载、分享热门手游资讯攻略教程、手机软件教程步骤,专注安卓手机游戏软件下载。本文链接:http://www.123down.cn/gonglue/227295.html