如果 SQLScript 过程需要执行动态 SQL 语句,其中部分派生自不受信任的输入(例如,用户界面),则存在 SQL 注入攻击的危险。可使用以下功能进行阻止:
示例:
create table mytab(myval varchar(20));
insert into mytab values('Val1');
create procedure change_value(
in tabname varchar(20),
in field varchar(20),
in old_val varchar(20),
in new_val varchar(20)
) as
begin
declare sqlstr nclob;
sqlstr := 'UPDATE "' ||:tabname || '" SET ' || field || ' = ''' ||
new_val || ''' WHERE ' || field || ' = ''' || old_val || '''';
exec(:sqlstr);
end
以下输入参数值能够以意外方式操作动态 SQL 语句:
set myval = ' ' --
如果验证和/或处理输入值,则无法发生这种情况:
create procedure change_value(
in tabname varchar(20),
in field varchar(20),
in old_val varchar(20),
in new_val varchar(20)
) as
begin
declare sqlstr nclob;
declare mycond condition for sql_error_code 10001;
if is_sql_injection_safe(field) <> 1 then
signal mycond set message_text = 'Invalid field ' || field;
end if;
sqlstr := 'UPDATE "' || escape_double_quotes(:tabname) || '" SET ' ||
field || ' = ''' || escape_single_quotes(:new_val) || ''' WHERE ' || field
|| ' = ''' || escape_single_quotes(:old_val) || '''';
exec(:sqlstr);
end
IS_SQL_INJECTION_SAFE([, ]) ::= 要检查的字符串。
::= < 值> 中允许的最大令牌数。缺省值为 1。
检查将用作 SQL 标识符的参数中可能的 SQL 注入。如果未找到可能的 SQL 注入,则返回 1,否则返回 0。
以下代码示例显示,如果参数中的令牌数与单个令牌的预期数量(默认值)不同,则该函数返回 0。
SELECT IS_SQL_INJECTION_SAFE('tab,le') "safe" FROM DUMMY;
safe
0
以下代码示例显示,如果参数中的标记数与预期的 3 个标记数匹配,则该函数返回 1。
SELECT IS_SQL_INJECTION_SAFE('CREATE STRUCTURED PRIVILEGE', 3) "safe" FROM DUMMY;
safe
1
ESCAPE_SINGLE_QUOTES() 转义给定字符串
以下代码示例显示了函数如何转义单引号。一个单引号在传递到函数时会用另一个单引号转义。然后,函数转义参数内容 Str'ing to Str''ing ,该参数从 SELECT 返回。
SELECT ESCAPE_SINGLE_QUOTES('Str''ing') "string_literal" FROM DUMMY;
string_literal
Str''ing
ESCAPE_DOUBLE_QUOTES() 转义给定字符串
以下代码示例显示 函数转义双引号。
SELECT ESCAPE_DOUBLE_QUOTES('TAB"LE') "table_name" FROM DUMMY;
table_name
TAB""LE