JDBI - @define和@bind在JDBI中有什么区别?

7

这两个函数是否都经过了SQL注入的净化/安全处理?例如,考虑以下代码:

@SqlUpdate("INSERT INTO <tableName> (<columns>) VALUES (<values>)")
    public abstract void addRowToDataset(@Define("tableName") String tableName, @Define("columns") String columns, @BindIn("values") Collection<Object> values);

我的理解是,@define 直接将字符串插入查询中,而 @bind 则进行了过滤。因此,如果我们控制了 columnstableName 参数,只有 values 参数是用户输入的,那么就不会出现问题。

2个回答

13

我遇到了同样的问题,并发现答案非常难找。一位同事告诉我,在一代程序员中它似乎是一种普遍的知识,所以随着软件的发展,它的文档可能被遗忘了。

事实上,Oracle的绑定和定义起初看起来很有前途,但却完全具有误导性,因为它的“定义”指的是设置引用以检索结果,这与JDBI中的含义完全不同。

如果我的同事正确,以下是它们实际的含义:

  • @Define 用于常量,并插入格式<field>
  • @Bind 用于变量,并插入格式:field(“命名参数”)。您是正确的:绑定的副作用是进行了过滤。
  • @BindIn 用于列表,并插入格式(element IN (<field>))。元素也经过了过滤。

我的错误在于对@Bind参数使用了<field>格式,这导致插值始终为空字符串。


我假设JNDI中的所有查询都是预处理语句,如果值未经过净化,那么如何使用define会导致SQL注入。 - crackerplace

0

在得到最多赞的回答之上,我只想补充一下,根据我的测试和解释:

  • @Bind 主要用于查询、更新/创建数据的地方。例如,在 WHEREVALUES(...) 之后。
  • @Define 主要用于 SQL 语句的其他部分,比如在条件或 ORDER BY 中使用:
@SqlQuery("SELECT * FROM $table ORDER BY <orderByWinsOrPlays>") 
fun getPlayerRankings(@Define orderByWinsOrPlays: String)

<orderByWinsOrPlays>替换为:orderByWinsOrPlays,并将@Define替换为@Bind("orderByWinsOrPlays")不起作用,但也不会抛出错误。测试这两个选项后,我得出了这个结论。而使用@Define注释的类型参数应该是一个原始对象,最好是,否则它将无法工作。对于复杂对象,请使用@BindBean


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接