`
irican
  • 浏览: 31652 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

PL/SQL的SQL注入

阅读更多

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;

/

 

 

1
0
分享到:
评论

相关推荐

    Oracle Advanced PL/SQL Developer Professional Guide

    除了编程之外,本书还提供了有关开发工具SQL Developer的使用的工具建议,采用数据库环境中的最佳实践并保护PL / SQL代码中的易受攻击区域以避免代码注入。 关于作者 Saurabh K. Gupta是一位经验丰富的数据库技术...

    pl/sql命令技巧

    pl/sql 最基本的使用命令,便于记忆,整理了一下,以后再补充

    SQL注入攻击与防御

    SQL注入是Internet上最危险、最有名的安全漏洞之一,本书是目前唯一一本专门致力于讲解SQL威胁的图书。本书作者均是专门研究SQL注入的安全专家,他们集众家之长,对应用程序的基本编码和升级维护进行全面跟踪,详细...

    PL/SQL for Apache-开源

    DSP代表Data Server Pages,即APACHE HTTP服务器模块,它为PL / SQL Server脚本提供变量注入预处理器,并在Oracle数据库后端具有有效的授权和认证框架。

    SQL注入攻击与防御(安全技术经典译丛)

    本书作者均是专门研究SQL注入的安全专家,他们集众家之长,对应用程序的基本编码和升级维护进行全面跟踪,详细讲解可能引发SQL注入的行为以及攻击者的利用要素,并结合长期实践经验提出了相应的解决方案。针对SQL...

    ora-exploits-classic:Oracle 经典注入漏洞利用库 - Perl 和 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安全扫描工具

    Nikto是一款Web安全扫描工具,可以扫描指定主机的web类型,主机名,特定目录,cookie,特定CGI漏洞,XSS漏洞,SQL注入漏洞等,非常强大滴说。。。 root@91ri.org:~# cd /pentest/web/nikto/ root@91ri.org:/pentest...

    易维论坛(IP.Board) v2.3.5 Final (PL2).zip

    一款获奖的可扩展的bbs系统,允许你很容易的创建,管理和和...* 修正: 可能造成远程 SQL 执行和注入的漏洞问题(PL1); * 修正: 由于验证码的问题造成的 Spam 垃圾发帖的问题(PL2); * 更新语言包和补充后台部分汉化.

    jdbc基础和参考

    提供预编译的功能,某种程度上可以避免sql注入的问题 4.提前做语法检查,在给?赋值的过程中要求数据类型一定要匹配,这样在某种程度上可以避免因为数据类型不匹配而发生的异常 CallableStatement:主要用来执行...

    MyBatis-plus 源码解析

    它在MyBatis原本的框架上增加了很多实用性功能,比如乐观锁插件、字段自动填充功能、分页插件、条件构造器、sql 注入器等等。使用 MyBatis-plus 可以完全不写任何 XML 文件,直接使用继承了BaseMapper 接口的对象...

    asp.net知识库

    最详细的SQL注入相关的命令整理 Oracle Oracle中PL/SQL单行函数和组函数详解 mssql+oracle Oracle编程的编码规范及命名规则 Oracle数据库字典介绍 0RACLE的字段类型 事务 CMT DEMO(容器管理事务演示) 事务隔离性的...

    php网络开发完全手册

    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-开源

    Powerfuzzer是一个高度自动化的Web模糊器,它基于许多其他可用的开源模糊器(包括cfuzzer,fuzzled,fuzzer.pl,jbrofuzz,webscarab,wapiti和Socket ... 它可以检测XSS,注入(SQL,LDAP,命令,代码,XPATH)和其他

    Spring JdbcTemplate 调用 Oracle 存储过程 与 Oracle 驱动下载

    1、关于 JdbcTemplate 的介绍、pom 依赖、DI 注入可以参考《Spring JdbcTemplate 模板剖析 之 常用 增删改查》,本文继续介绍 JdbcTemplate 调用数据库的存储过程,虽然 Mysql 也有存储过程,但是为了尽可能的多覆盖...

    Java学习笔记-个人整理的

    {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}批处理模式}{...

Global site tag (gtag.js) - Google Analytics