gpt4 book ai didi

database - 多态函数的 SQL 注入(inject)安全调用

转载 作者:搜寻专家 更新时间:2023-10-30 23:45:57 26 4
gpt4 key购买 nike

有好几次我发现自己在重构 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 的行。我见过的最好的例子是 this polymorphic function使用 anyelement 类型,并被称为

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

但是在上面的代码中调用它需要

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

也就是说,它需要将关系名称粘贴到查询中,这有 SQL 注入(inject)的风险。那么,是否可以保留存储过程的多态优点,但允许使用通用关系名称调用它?

最佳答案

我觉得这样不行。我假设 Groovy 在这里使用准备好的语句,这要求输入和返回类型在准备时已知,而我的函数从多态输入类型派生返回类型。

我很确定您需要字符串连接。但不要担心,有像 pg_escape() 这样的函数可以清理表名并使 SQLi 变得不可能。不知道 Groovy,但它也应该有。

或者是吗?

基于此相关答案末尾的函数 data_of(..):

PREPARE我可以通过显式声明返回类型来完成这项工作:

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

然后我可以提交 NULL,它从准备好的上下文中转换为 "relationName":

EXECUTE fooplan(NULL, 1);

因此,如果您的界面支持的话,这毕竟是可行的。但是您仍然必须将表名连接为返回数据类型(因此可以抵御 SQLi)。我猜是 catch 22。

关于database - 多态函数的 SQL 注入(inject)安全调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28575899/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com