jsonb_path_exists with Ef Core and Npgsql causes sql injection

问题描述 投票:0回答:1

我有一个查询和两个参数。 uuid 和文本。 NpgsqlParameter 正在将值转换为单引号,这会导致语法错误。

jsonb_path_exists
中必须有双引号。

代码:

var idParam = new NpgsqlParameter("id", NpgsqlDbType.Uuid) { Value = id};
var queryParam = new NpgsqlParameter("q", NpgsqlDbType.Text) { Value = q };
var sql = @"SELECT * FROM ""MyTable""
           WHERE jsonb_path_exists(""Value"",
                    '$[*] ? (@.id == @id && @.text like_regex @q flag ""i"" )')";
var rawSql = Context.MyTable.FromSqlRaw(sql, idParam, queryParam);

如果我将类型设置为

NpgsqlDbType.JsonPath
它可以正常工作但容易受到 sql 注入

var condition = $"'$[*] ? (@.id == \"{id}\"  && @.text like_regex \"{q}\"  flag \"i\" )'";
var jsonPathParam = new NpgsqlParameter("jsonPath", NpgsqlDbType.JsonPath) { Value = $"({condition})" };

ef core 和 npgsql 版本是 6.0.4

edit:是否有可能在不运行查询的情况下检测到容易受到

queryParam
的 sql 注入攻击

c# .net postgresql entity-framework-core npgsql
1个回答
0
投票

Npgsql 似乎有一个错误,导致它错误地转义 JSON 路径参数。我建议你在他们的 Github repo 上将此作为错误 归档。

要解决它,您可以尝试对参数进行横向连接

var idParam = new NpgsqlParameter("id", NpgsqlDbType.Uuid) { Value = id};
var queryParam = new NpgsqlParameter("q", NpgsqlDbType.Text) { Value = q };
var sql = @"
SELECT t.*
FROM MyTable AS t
CROSS JOIN LATERAL (VALUES
    (@id, @q)
) AS v(id, q)
WHERE jsonb_path_exists(
    t.Value,
    '$[*] ? (@.id == v.id && @.text like_regex v.q flag ""i"")'
);
";
var rawSql = Context.MyTable.FromSqlRaw(sql, idParam, queryParam);
© www.soinside.com 2019 - 2024. All rights reserved.