SQL注入,一个老掉牙的安全问题,有SQL的地方就会有SQL注入。一般做企业应用的只关注Java层面的编写规范,比如使用preparedStatement,或者干脆直接过滤掉危险字符等等。
其实在编写PL/SQL的function或procedure的时候,也存在注入的问题,我们来简单探讨一下。
例如有这样一个procedure,功能为禁用某个table的constraint:
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;
/
了解SQL注入的同学应该可以看出来,上面的procedure存在几个危险的变量:
1. p_table
2. p_constraint_name
3. p_schema
前两者容易发现,但为什还有p_schema呢?因为当前的USER名字也有可能是用户构造的危险字符串。
好了,根据一般规律,我们应该遵循以下顺序进行修改:
1. 静态SQL。能不使用变量就不使用。
2. 绑定变量。与Java中的PreparedStatement类似,不把数据直接拼接在sql里,而是存入变量中,直接被数据库使用。
3. 检查变量的值。
显然,前两个方法对这个procedure不适用。我们只能使用最不爽的第3个方法。
好在对于PL/SQL来说,我们不用自己编写复杂的字符判断。Oracle有个SYS.DBMS_ASSERT包,提供了一些预置的function,如下:
NOOP |
No Operation. Returns string unchanged |
SIMPLE_SQL_NAME |
Verify that the input string is a simple SQL name. |
QUALIFIED_SQL_NAME |
Verify that the input string is a qualified SQL name. |
SCHEMA_NAME |
This function verifies that the input string is an existing schema name. |
SQL_OBJECT_NAME |
This function verifies that the input parameter string is a qualified SQL identifier of an existing SQL object. |
ENQUOTE_NAME |
This function encloses a name in double quotes. |
ENQUOTE_LITERAL |
Add leading and trailing single quotes to a string literal. |
(请参考:http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_assert.htm)
在执行这些function时,如果传入的变量不满足规定的格式或条件,则会抛异常,从而保护我们自己的procedure不被SQL注入。
我们判断这些方法是否可用:
1. SIMPLE_SQL_NAME, QUALIFIED_SQL_NAME
这些方法要求用户出入的参数本身是一个有效的sql名字。比如,如果有个table名为"Table One",那么就要求传入的值中包含双引号。使用这些方法存在一个问题,直接从data-dictionary读取出来的table名字是不带双引号的。如果用户直接从data-dictionary中读取table名字,然后直接传入我们的procedure,则会因为它不满足simple sql name的要求而抛异常,但实际上这个table名字应该是正确的。所以不能直接使用这些function。
2. SCHEMA_NAME, SQL_OBJECT_NAME
这些方法要求传入的参数值是数据库中已经存在的对象名字。如果数据库中本来有个table名为 "Table One",那么如果用户传入Table One,则被视为正确。使用这些方法,避免了第一个方法的data-dictionary问题,而且也能够避免遭受类似table' -- 的问题。但存在所谓二次攻击的问题。如果用户提前创建了一个包含危险字符的table,然后再调用我们的procedure,依旧会造成SQL注入。
3. ENQUOTE_NAME, ENQUOTE_LITERAL
这些方法直接把参数的值用双引号或单引号括起来。如果括起来之后的值本身还存在危险的话,会抛异常。对于我们举例的procedure来说,只需要使用ENQUOTE_NAME。ENQUOTE_NAME需要两个参数,一个是需要enquote的变量,另一个为是否转换为大写。现在,对于我们的procedure,应该使用ENQUOTE_NAME(p_table, FALSE),保证Table One不被转换为"TABLE ONE"。
这是我们的最终解决方案。但需要注意的是,由于使用了ENQUOTE_NAME,对于我们的procedure来说,table和constraint的名字对大小写敏感。如果名为table_1,则必须传入TABLE_1,否则会执行错误。
修改后的代码如下:
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;
/
分享到:
相关推荐
除了编程之外,本书还提供了有关开发工具SQL Developer的使用的工具建议,采用数据库环境中的最佳实践并保护PL / SQL代码中的易受攻击区域以避免代码注入。 关于作者 Saurabh K. Gupta是一位经验丰富的数据库技术...
pl/sql 最基本的使用命令,便于记忆,整理了一下,以后再补充
SQL注入是Internet上最危险、最有名的安全漏洞之一,本书是目前唯一一本专门致力于讲解SQL威胁的图书。本书作者均是专门研究SQL注入的安全专家,他们集众家之长,对应用程序的基本编码和升级维护进行全面跟踪,详细...
DSP代表Data Server Pages,即APACHE HTTP服务器模块,它为PL / SQL Server脚本提供变量注入预处理器,并在Oracle数据库后端具有有效的授权和认证框架。
本书作者均是专门研究SQL注入的安全专家,他们集众家之长,对应用程序的基本编码和升级维护进行全面跟踪,详细讲解可能引发SQL注入的行为以及攻击者的利用要素,并结合长期实践经验提出了相应的解决方案。针对SQL...
Oracle 经典注入漏洞存储库 - Perl 和 SQL 版本 SQL ctxsys-drvxtabc-create_tables.sql dbms_cdc_subscribe.sql dbms_exp_ext.sql dbms_meta_get_ddl.sql kupm-mcpmain.sql kupv-ft_attach...
在书店也看到了许多数据库优化的专业书籍,但是感觉更多是面向DBA或者是PL/SQL开发方面的知识,个人感觉不太适合普通程序员。而要想做到数据库优化的高手,不是花几周,几个月就能达到的,这并不是因为数据库优化有...
Nikto是一款Web安全扫描工具,可以扫描指定主机的web类型,主机名,特定目录,cookie,特定CGI漏洞,XSS漏洞,SQL注入漏洞等,非常强大滴说。。。 root@91ri.org:~# cd /pentest/web/nikto/ root@91ri.org:/pentest...
一款获奖的可扩展的bbs系统,允许你很容易的创建,管理和和...* 修正: 可能造成远程 SQL 执行和注入的漏洞问题(PL1); * 修正: 由于验证码的问题造成的 Spam 垃圾发帖的问题(PL2); * 更新语言包和补充后台部分汉化.
提供预编译的功能,某种程度上可以避免sql注入的问题 4.提前做语法检查,在给?赋值的过程中要求数据类型一定要匹配,这样在某种程度上可以避免因为数据类型不匹配而发生的异常 CallableStatement:主要用来执行...
它在MyBatis原本的框架上增加了很多实用性功能,比如乐观锁插件、字段自动填充功能、分页插件、条件构造器、sql 注入器等等。使用 MyBatis-plus 可以完全不写任何 XML 文件,直接使用继承了BaseMapper 接口的对象...
最详细的SQL注入相关的命令整理 Oracle Oracle中PL/SQL单行函数和组函数详解 mssql+oracle Oracle编程的编码规范及命名规则 Oracle数据库字典介绍 0RACLE的字段类型 事务 CMT DEMO(容器管理事务演示) 事务隔离性的...
15.3.3 执行SQL语句 242 15.3.4 获得查询结果集中的记录数 243 15.3.5 获得结果集中的某一条记录 244 15.3.6 逐行获取结果集中的每一条 15.3.6 记录 245 15.3.7 结果集的分页 248 15.3.8 用户动态添加记录 249 15.3....
Powerfuzzer是一个高度自动化的Web模糊器,它基于许多其他可用的开源模糊器(包括cfuzzer,fuzzled,fuzzer.pl,jbrofuzz,webscarab,wapiti和Socket ... 它可以检测XSS,注入(SQL,LDAP,命令,代码,XPATH)和其他
1、关于 JdbcTemplate 的介绍、pom 依赖、DI 注入可以参考《Spring JdbcTemplate 模板剖析 之 常用 增删改查》,本文继续介绍 JdbcTemplate 调用数据库的存储过程,虽然 Mysql 也有存储过程,但是为了尽可能的多覆盖...
{12.25}PL/SQL}{189}{section.12.25} {13}JDBC}{191}{chapter.13} {13.1}forName}{191}{section.13.1} {13.2}JDBC}{191}{section.13.2} {13.3}连接Oracle数据库及操作}{192}{section.13.3} {13.4}批处理模式}{...