一种方法相对于另一种方法是否具有特殊优势?
#1 楼
这取决于。SQL函数
对于
LANGUAGE sql
来说,答案通常是肯定的。只要您不调用不安全的函数,就将传递的参数视为值,并且无法进行SQL注入从正文和传递参数开始。
PL / pgSQL函数
对于
LANGUAGE plpgsql
来说,答案通常是肯定的。但是,PL / pgSQL允许在动态SQL中将传递的参数(或部分)串联在一起到查询字符串并使用
EXECUTE
执行。这样可以将用户输入转换为SQL代码,并使SQL注入成为可能。您无法从外部判断功能主体是否正确处理了它。提供了工具。仅在需要时使用动态SQL。使用参数作为值的普通SQL语句可以像SQL函数一样防止SQL注入。
对于动态SQL,最好将值作为值传递给以下内容:
USING
子句。示例。使主体上无法进行SQL注入。
如果在SQL字符串中连接值,请使用:
format()
和格式说明符%L
。例如。quote_literal()
或quote_nullable()
。示例。安全地将字符串括在单引号中,从而避免了语法错误和SQL注入。
使用以下参数将处理参数视为SQL字符串中的标识符:
format()
,带有格式说明符%I
。示例。quote_ident()
。例如。表名称:
regclass
的注册类型转换为_tbl::regclass
。示例。在需要的地方安全地将标识符字符串用双引号引起来,从而避免语法错误和SQL注入。
相关:
将PL / pgSQL函数重构为返回各种SELECT查询的输出
将表和列名定义为plpgsql函数中的参数?
永远不要仅仅根据用户输入来构建字符串并执行。这包括由用户直接传递或从系统目录中获取的标识符。构建动态SQL时,所有内容都应视为用户输入并适当引用!
此相关答案中有关性能含义的更多信息:
函数性能
SQL的基础-injection:
http://bobby-tables.com/
类似的注意事项也适用于其他允许动态SQL的服务器端语言。
评论
因此,总而言之:如果1)我仅使用语言sql,则很安全; 2)如果我使用plpgslq但未执行,我很安全; 3)如果我使用plpgsql并执行但没有标识符和%s或% L是适当的,我很安全,或者4)如果我使用plpgsql并执行和标识符,但%I或quote_ident则我是安全的。正确?
– MickeyfAgain_BeforeExitOfSO
2013年9月12日在17:28
@mickeyf:基本上是。另外,尽可能使用USING子句将值传递给EXECUTE。您可以从SQL函数中调用PL / pgSQL函数并传递参数。因此,绝对正确,只要您不直接或间接调用任何不安全的函数,便可以安全。如果所有功能都正确完成,那将不会发生。
–欧文·布兰德斯特(Erwin Brandstetter)
2013年9月12日21:13在