【发布时间】:2018-04-04 06:38:23
【问题描述】:
我可以使用 PostgreSQL 的美元引号字符串常量安全地防止 SQL 注入吗?
我知道处理动态查询的最佳方法是让它们在具有参数化查询的应用程序层中生成,这不是这个问题的内容。所有的业务逻辑都在存储过程中。
我有一个存储过程,它接受参数并生成查询、运行它、格式化结果并将其作为文本块返回。这个函数传递了一个表名、列名和 WHERE 参数。传递给函数的 WHERE 参数来自用户在数据库中输入的数据。我想确保对 sts 进行清理,以便构建的查询是安全的。
使用 PostgreSQLs Dollar-Quoted Strings Constants,我应该能够安全地清理除“ $$ ”之外的所有字符串输入。但是,如果我对 "$" 进行字符串替换以对其进行转义,我应该能够进行安全的字符串比较。
存储过程:
function_name(tablename text, colnames text[], whereparam text)
--Build dynamic query...
函数调用:
SELECT
function_name('tablename', ARRAY['col1', 'col2', 'col3'], 'AND replace(col1, ''$'', ''/$'') = $$' || replace(alt_string_col, '$', '/$') || '$$ ')
FROM alttable
WHERE alt_id = 123;
查询生成:
SELECT col1, col2, col3 FROM tablename WHERE 1=1 AND replace(col1, '$', '/$') = $$un/safe'user /$/$ data;$$
由于我在将 col1 字段与转义的用户数据进行比较之前对其进行转义,因此即使用户输入“un/safe'user $$ data;”也是如此在字段 alt_string_col 中,双美元符号不会中断查询并且比较通过。
这是在 PostgreSQL 存储过程中转义字符串的安全方法吗?
编辑1
感谢欧文·布兰德施泰特。为EXECUTE 使用USING 子句我正要创建一个可以像这样调用的函数:
SELECT function_name(
'tablename',
ARRAY['col1', 'col2', 'col3'],
ARRAY[' AND col1 = $1 ', ' OR col2 = $5 '],
quote_literal(alt_string_col)::text, --Text 1-4
NULL::text,
NULL::text,
NULL::text,
alt_active_col::boolean, --Bool 1-4
NULL::boolean,
NULL::boolean,
NULL::boolean,
NULL::integer, --Int 1-4
NULL::integer,
NULL::integer,
NULL::integer
)
FROM alttable
WHERE alt_id = 123;
它为可以传入的 WHERE 子句提供了一些灵活性。
在存储过程中,EXECUTE 语句有类似的内容。
FOR results IN EXECUTE(builtquery) USING
textParm1,
textParm2,
textParm3,
textParm4,
boolParm1,
boolParm2,
boolParm3,
boolParm4,
intParm1,
intParm2,
intParm3,
intParm4
LOOP
-- Do some stuff
END LOOP;
【问题讨论】:
标签: postgresql stored-procedures sql-injection sanitization