DB2静态/动态SQL语句与SQL注入攻击

本文对比了DB2中静态SQL与动态SQL的区别,说明了静态SQL如何通过预先确定的访问路径有效防止SQL注入攻击。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在指导一个小型DB2项目开发时,突然想到了为什么SQL注入攻击之类的黑客技术在我接受的DB2的mainframe项目中根本没有提及,应该就是因为DB2的静态SQL语句机制。

 

我们先来看定义。

静态SQL:在编程语言中,语句以hard code的方式写在程序中,但是其中允许有变量。这样的程序需要经过DB2预编译,将对这样的SQL语句的调用变成native language call。而实际的SQL语句则会被BIND成为DB2系统中的可执行包,与应用程序绑定,被其调用。

典型的静态SQL:

EXEC SQL

  UPDATE TESTTABLE SET

    COL1 = :VALUE1

    COL2 = :VALUE2

  WHERE COL3 LIKE :VALUE3

END-EXEC.

其中,COL1, COL2, COL3是TABLE COLUMN名字,而VALUE1, VALUE2, VALUE3是应用程序的NATIVE VARIABLE。

目前,商业DB2应用程序采用的大多是静态SQL,特点是一次BIND,多次稳定运行,省去了数据库每次寻找ACCESS PATH的OVER HEAD,并且,如果环境迁移,只须重新BIND,而不需要重新编译应用程序或该产品配置。

 

动态SQL:在编程语言中,语句以动态的VARIABLE的方式,提交给DB2运行。每次需要PREPARE STATEMENT FROM A VARIABLE,然后再EXECUTE。最常见的这类应用就是JDBC, ODBC这样的调用。其缺点是,每次运行都需要数据库决定ACCESS PATH,造成了很多OVERHEAD,但是同时如果表中数据信息时常变动,由于每次都做优化处理,有时也会增进性能。

 

SQL注入攻击是指在提交查询表单时,故意的输入一些SQL保留字,以扰乱程序执行的SQL语句,甚至插入攻击者指定的SQL语句执行。这样的攻击常见于ASP + MS SQL server,但并不局限于此。

 

比如,某应用提供查询数据库中所有职员姓名信息的功能,要求使用者输入姓名,比如SMITH,便查询出所有姓名为SMITH的职员的员工号。

假设,程序中构造sql的逻辑如下:

SQLSTMT = "SELECT EMP_ID FROM EMP_TABLE WHERE EMP_NAME LIKE /'" +

                   NAME_FROM_UI + "/'";

EXECUTE SQLSTMT;

则构造出的SQL如下:

SELECT EMP_ID

FROM EMP_TABLE

WHERE EMP_NAME LIKE 'SMITH';

黄色的字符为从UI接收的输入,下同)

则查询正确;

但是,攻击者如果提交这样的一个姓名:

SMITH'; UPDATE EMP_TABLE SET SALARY = 100000;

如果程序中没有对SQL特殊字符'做转义处理,则生成的SQL就是:

SELECT EMP_ID

FROM EMP_TABLE

WHERE EMP_NAME LIKE 'SMITH'; UPDATE EMP_TABLE SET SALARY = 100000; ';

这样,假设表中真的有SALARY这个COLUMN,并且例子中处理从UI接受到的字串时没有对'进行转义处理,攻击者就能将所有人的薪水改为100000。

(实际上,SQL注入攻击并不是简单转义'就能避免的,攻击者可以直接使用&加'的UNICODE编码来规避程序转义等,在此不深入探讨)

(SQL注入攻击可以有多种方法获取表名、列名,而不仅仅是全凭猜测,最常见的手法为先注入描述表的SQL语句,获取表信息后进行实际攻击等等,在此不再详述,有兴趣的读者可以自己GOOGLE一下。)

 

以上的攻击,对于动态SQL语句来说,无疑是可以成功的,因为每次执行,数据库都会为这个语句重新确定ACCESS PATH,所以,即使每次语句不同,其执行也不会跑出错误。

而如果是静态SQL语句,由于其ACCESS PATH已经确定,换言之,在上例中就意味着,SELECT语句要使用的索引,优先APPLY过滤条件的顺序之类,都已经确定的写在DB2的系统表中了,这时,如果试图使用SQL注入攻击,DB2已经明确的知道了,要做的查询是什么,并且已经知道了,传进来的变量仅用于过滤条件,这样就杜绝了在查询中注入攻击者的SQL语句的可能。

笔者在毫无输入转义判定的DB2应用程序(静态SQL语句)中测试了例中的注入攻击,结果是DB2正确返回SQLCODE 100,提示找不到需要查询的记录。

 

由此笔者认为,在使用静态SQL语句的DB2应用程序中,应无SQL注入攻击之虞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值