1

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

我想允许客户端查询具有固定列和 JSONB 约束的数据库。很容易翻译一些查询参数,例如?field=value并将其转换为固定列的参数化 SQL 查询,但我也想向 SQL 添加任意 JSONB 查询。

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

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

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

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

编辑:客户端可能对 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 注入。例如,一个简单且可能不充分的解决方案是不允许任何“;” 在查询字符串中。

4

1 回答 1

0

您可以允许用户在 JSON 文档中指定路径,然后在调用类似json_extract_path_text. 也就是说,WHERE 子句看起来像:

WHERE json_extract_path_text(data, $1) = $2

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

于 2020-08-06T01:21:03.187 回答