多态函数的SQL注入安全通话(SQL Injection-safe call of polymorp

2019-10-21 23:05发布

有好几次,我发现自己重构Web应用程序代码,并最终想要做这样的事情(的Groovy在这种情况下,但可以是任何东西):

Map getData(String relationName, Integer rowId) {
    def sql = Sql.newInstance([...])
    def result = sql.firstRow('SELECT getRelationRow(?,?)', relationName, rowId)
    sql.close()
    return new HashMap(result)
}

其中所存储的程序getRelationRow(relname text, rowid integer)执行动态sql检索指定的行rowid在所请求的关系。 我见过这样的功能的最好的例子就是这种多态函数使用anyelement类型,被称为

SELECT * FROM data_of(NULL::pcdmet, 17);

然而,为了把这个在上面的代码需要

def result = sql.firstRow("SELECT * FROM data_of(NULL::${relationName},?)",  rowId)

也就是说,它需要的关系名称粘贴到查询,哪些风险SQL注入。 那么,有没有去保持存储过程的多态性善良,但允许它与一般的关系,名字叫?

Answer 1:

我不认为这是可以做到这样。 我认为Groovy的是这里使用预处理语句 ,这就要求输入和返回类型都在准备时已知的,而我的函数可从多态输入类型的返回类型。

我敢肯定,你需要字符串连接。 不过不要担心,有喜欢的功能pg_escape()来消毒表名,使SQLI是不可能的。 不知道Groovy的,但它应该有这一点。

确实如此吗?

基于功能data_of(..)在此相关答案的结尾:

  • 重构一个PL / pgSQL函数返回不同的SELECT查询的输出

随着PREPARE我可以明确地声明的返回类型,使这项工作:

PREPARE fooplan ("relationName") AS  -- table name works as row type
SELECT * FROM data_of($1, $2);

然后,我可以在手NULL ,它被转换为"relationName"从所准备的上下文:

EXECUTE fooplan(NULL, 1);

所以这可能毕竟工作,如果你的接口支持这一点。 但是你还是要串联表名为返回的数据类型(因此抵御SQLI)。 抓住22我猜。



文章来源: SQL Injection-safe call of polymorphic function