2011-12-01 SQL注入的防备
http://www.itpub.net/thread-1499223-21-1.html
207楼
我创建如下的两张表并填入数据:
CREATETABLEplch_names1(nameVARCHAR2(100))/CREATETABLEplch_names2(nameVARCHAR2(100))/BEGININSERTINTOplch_names1VALUES('Paul');INSERTINTOplch_names1VALUES('Ringo');INSERTINTOplch_names1VALUES('John');INSERTINTOplch_names1VALUES('George');INSERTINTOplch_names2VALUES('Jerry');INSERTINTOplch_names2VALUES('Bob');INSERTINTOplch_names2VALUES('Phil');COMMIT;END;/
然后我创建了这个函数来返回一个游标,里面包含了指定表名的name列的数据:
CREATEORREPLACEFUNCTIONplch_get_names(table_inINVARCHAR2)RETURNSYS_REFCURSORISl_cvSYS_REFCURSOR;BEGINOPENl_cvFOR'selectnamefrom'||table_in||'orderbyname';RETURNl_cv;ENDplch_get_names;/
这里是一个“帮手”过程来显示这个函数所返回的数据:
CREATEORREPLACEPROCEDUREplch_show_names(table_inINVARCHAR2)ISl_cvSYS_REFCURSOR;l_nameplch_names1.name%TYPE;BEGINDBMS_OUTPUT.put_line('Namesin'||table_in);l_cv:=plch_get_names(table_in);LOOPFETCHl_cvINTOl_name;EXITWHENl_cv%NOTFOUND;DBMS_OUTPUT.put_line(l_name);ENDLOOP;CLOSEl_cv;ENDplch_show_names;/
当我执行下列这个代码块,我可以看到Beatles 和 Grateful Dead乐队的成员。(即上述两张表中的数据)
BEGINplch_show_names('plch_names1');plch_show_names('plch_names2');END;/
不幸的是,如果我这样来执行:
BEGINplch_show_names('plch_names2where1=2unionselectusernamefromall_users--');END;/
我看到了数据库实例中所有用户的名字,这属于安全违规(是一种SQL注入)
下面哪些plch_get_names函数会抛出异常,假如调用时传入了那个“注入”参数值,但是如果传入像plch_names1 和 plch_names2这样的“真实”表名你还可以看到表中数据?
(A)
BEGINOPENl_cvFOR'selectnamefrom'||DBMS_ASSERT.simple_sql_name(table_in)||'orderbyname';RETURNl_cv;ENDplch_get_names;
(B)
BEGINDBMS_ASSERT.simple_sql_name(table_in);OPENl_cvFOR'selectnamefrom'||table_in||'orderbyname';RETURNl_cv;ENDplch_get_names;
(C)
BEGINOPENl_cvFOR'selectnamefrom'||DBMS_ASSERT.qualified_sql_name(table_in)||'orderbyname';RETURNl_cv;ENDplch_get_names;
(D)
BEGINOPENl_cvFOR'selectnamefrom:table_nameorderbyname'USINGtable_in;RETURNl_cv;ENDplch_get_names;
答案说明在209楼
2011-12-01答案AC.DBMS_ASSERT.SIMPLE_SQL_NAME检查一个名字是否为SQL中可用的简单名字:名字必须以字母开头,随后可跟随数字、字母或_,$,#字符;允许带双引号,双引号之间可以是任意字符;假如双引号之内的名字本身就带有双引号,那么必须重复双引号两次来表示;输入参数如果前后带有空格被忽略。名字的长度没有被检测。DBMS_ASSERT.qualified_sql_name则更宽松一些,允许带.(小数点,比如用在记录成员、PACKAGE里面的函数、SCHEMAOWNER等)和@(用在DBLINK)答案B:simple_sql_name是函数不是存储过程,必须将返回值赋给变量。答案D:表名不可以用绑定变量。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。