Ecto的片段允许SQL注入

当 Ecto 查询变得更复杂并且需要像 那样的子句时CASE...WHEN...ELSE...END,我们倾向于依赖 Ectofragment来解决它。

例如 query = from t in <Model>, select: fragment("SUM(CASE WHEN status = ? THEN 1 ELSE 0 END)", 2)

事实上,关于这个主题的最流行的 Stack Overflow 帖子建议创建一个这样的宏:

defmacro case_when(condition, do: then_expr, else: else_expr) do
  quote do
    fragment(
      "CASE WHEN ? THEN ? ELSE ? END",
      unquote(condition),
      unquote(then_expr),
      unquote(else_expr)
    )
  end
end

因此您可以在 Ecto 查询中以这种方式使用它:

query = from t in <Model>,
  select: case_when t.status == 2
    do 1
    else 0
  end

同时,在另一篇文章中,我发现了这个:

(Ecto.Query.CompileError) to prevent SQL injection attacks, fragment(...) does not allow strings to be interpolated as the first argument via the `^` operator, got: `"exists (n        SELECT 1n        FROM #{other_table} on        WHERE o.column_name = ?)"

好吧,似乎 Ecto 的团队发现人们正在使用它fragment来解决复杂的查询,但他们没有意识到它会导致 SQL 注入,因此他们不允许将字符串插值作为保护开发人员的一种方式。

然后另一个人说“别担心,使用宏”。

我不是灵丹妙药专家,但这似乎是一种使用字符串插值的解决方法,逃避fragment保护。

有没有办法使用片段并确保查询已参数化?

以上是Ecto的片段允许SQL注入的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>