如何防止使用外部客户端提供的任意JSONB查询字符串进行SQL注入



我有一个由PostgreSQL数据库支持的基本REST服务,该数据库有一个包含多个列的表,其中一个列是包含任意数据的JSONB列。客户端可以存储填充在固定列中的数据,并将任何JSON作为存储在JSONB列中的不透明数据提供。

我希望允许客户端在固定列和JSONB上都有约束的情况下查询数据库。翻译一些查询参数(如?field=value(并将其转换为固定列的参数化SQL查询是很容易的,但我也想向SQL中添加一个任意的JSONB查询。

这个JSONB查询字符串可能包含SQL注入,我如何防止这种情况发生?我认为,因为JSONB数据的结构是任意的,所以我不能为此目的使用参数化查询。我能找到的所有文档都建议我使用参数化查询,而且我找不到任何关于如何真正净化查询字符串本身的有用信息,这似乎是我唯一的选择。

例如,类似的问题是:如何防止PostgreSQL JSON/JSONB字段中的SQL注入?

但我无法应用相同的解决方案,因为我不知道JSONB或查询的结构,我不能假设客户端想要使用特定的运算符查询特定的路径,整个JSONB查询需要由客户端免费提供。

我正在使用golang,以防有任何现有的库或代码片段可以使用。

edit:客户端可能对JSONB进行的一些示例查询:

(content->>'company') is NULL
(content->>'income')::numeric>80000
content->'company'->>'name'='EA' AND (content->>'income')::numeric>80000
content->'assets'@>'[{"kind":"car"}]'
(content->>'DOB')::TIMESTAMP<'2000-01-30T10:12:18.120Z'::TIMESTAMP
EXISTS (SELECT FROM jsonb_array_elements(content->'assets') asset WHERE (asset->>'value')::numeric > 100000)

请注意,这些并没有涵盖所有可能的查询类型。理想情况下,我希望PostgreSQL在JSONB数据上支持的任何查询都被允许。我只想检查查询以确保它不包含sql注入。例如,一个简单且可能不充分的解决方案是不允许任何"在查询字符串中。

您可以允许用户在JSON文档中指定一个路径,然后在对json_extract_path_text等函数的调用中参数化该路径。也就是说,WHERE子句看起来像:

WHERE json_extract_path_text(data, $1) = $2

path参数只是一个字符串,很容易参数化,它描述了向下遍历到给定值的键,例如'foo.bars[0].name'。子句的右侧将按照用于固定列筛选的相同规则进行参数化。

最新更新