我有两个字符串:
- 'UPP'
- '呃'
和值,例如'a'。
我需要调用函数UPPER
(从两个字符串合成)并将值作为参数传递。
我怎样才能做到这一点?
(实际上,我需要将函数交叉表与列计数器连接起来......)
我有两个字符串:
和值,例如'a'。
我需要调用函数UPPER
(从两个字符串合成)并将值作为参数传递。
我怎样才能做到这一点?
(实际上,我需要将函数交叉表与列计数器连接起来......)
使用动态 SQL 的函数的存根可能如下所示:
CREATE OR REPLACE FUNCTION f_exec(text, text, text, OUT result text)
RETURNS text AS
$func$
BEGIN
EXECUTE 'SELECT ' || $1 || $2 || '($1)' -- last $1 not referring func param
INTO result
USING $3;
END
$func$ LANGUAGE plpgsql;
称呼:
SELECT f_exec('up', 'per', 'a')
不要混淆,$1
内部有自己的作用域EXECUTE
,指的是USING
子句传入的参数,而不是外部函数参数。
这为SQL 注入打开了大门!
阅读关于 dba.SE 的相关问题下的建议以及手册中的“安全地编写SECURITY DEFINER
函数”一章。
在这种特殊情况下,有一种避免 SQLi的聪明方法:
CREATE OR REPLACE FUNCTION f_exec(
func1 text
,func2 text
,param text
,OUT result text) AS
$func$
DECLARE
funcname text := (func1 || func2)::regproc;
BEGIN
EXECUTE 'SELECT ' || funcname || '($1)::text'
INTO result
USING param;
END
$func$ LANGUAGE plpgsql;
转换为对象标识符类型regproc
$1
有效地清除了通过and注入除有效函数名之外的任何内容的所有尝试$2
。该子句已经消除了通过( )USING
注入代码的尝试。$3
param
还:
RETURNING
子句,因为OUT
参数会处理它。text
因为我们不知道函数的实际返回类型,并且 Postgres 中的每个数据类型都可以转换为text
. IN
类型的参数,text
否则会出现异常。