如何使用 EXPLAIN 命令避免 PostgreSQL 中的 SQL 注入?

How to avoid SQL injection in PostgreSQL using the EXPLAIN command?

提问人:Matteo 提问时间:8/3/2023 更新时间:8/4/2023 访问量:70

问:

据我所知,不接受带参数的查询:EXPLAIN (ANALYZE, ...)

EXPLAIN (ANALYZE) SELECT * FROM mytable WHERE name = $1它会产生一个错误:ERROR: there is no parameter $1 at character 107

所以我不能使用参数绑定。db.Query(myquery, params...)

如何使用我想要的任何参数安全地运行命令?我是否需要获取一个清理 sql 字符串的包?我正在构建一个程序,通过接受用户输入来自动解释查询。EXPLAIN

postgresql sql 注入

评论

0赞 Your Common Sense 8/4/2023
但是,执行计划是否取决于提供的值?为什么不能只是 1 美元而不是 1 美元?
0赞 Your Common Sense 8/4/2023
另外,我不明白你在说什么。要分析的完整 SQL 查询?
0赞 Laurenz Albe 8/4/2023
@YourCommonSense 是的,执行计划将取决于参数值,除非 PostgreSQL 决定使用通用计划,这只会发生在计划被缓存的语句中,并且仅在执行几次后发生。

答:

1赞 Laurenz Albe 8/4/2023 #1

你能做的最好的事情是创建一个准备好的语句:

PREPARE stmt(text) AS SELECT * FROM mytable WHERE name = $1;

然后你可以

EXPLAIN EXECUTE stmt('some name');

获取执行计划,而无需在语句中插入字符串。如果不想让预准备语句一直存在到数据库会话结束,则可以这样做。DEALLOCATE

如果不希望考虑参数值,可以使用

EXPLAIN (GENERIC_PLAN) SELECT * FROM mytable WHERE name = $1;

这将为您提供通用计划,并且从 PostgreSQL v16 开始可用。

评论

0赞 Matteo 8/4/2023
感谢您对 Postgres 的回答和贡献!
0赞 Matteo 8/4/2023
还有一个问题:与在没有预准备语句的情况下运行查询相比,以这种方式运行会改变计划的输出?EXPLAIN
1赞 Laurenz Albe 8/4/2023
不,结果应该是相同的。