.net 带有Ef核心和Npgsql的jsonb_path_exists导致sql注入

cnwbcb6i  于 2023-03-31  发布在  .NET
关注(0)|答案(1)|浏览(122)

我有一个查询和两个参数。uuid和text。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核心和npgsql版本是6.0.4

6pp0gazn

6pp0gazn1#

似乎Npgsql中有一个bug,导致它错误地转义JSON路径参数。我建议你在他们的Github仓库上file this as a bug
要解决这个问题,可以尝试进行参数的横向连接

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);

相关问题