postgresql PG 8000或Postgres客户端-服务器协议是否不支持SQL语句中的绑定参数?

enxuqcxy  于 2023-10-18  发布在  PostgreSQL
关注(0)|答案(2)|浏览(144)

我正在尝试创建一个PG8000的新用户。这段代码可以工作,但它将密码放在服务器日志中,这是不可取的(我不关心这个用例的SQL注入):

with pg8000.dbapi.connect(**CONNECTION_INFO) as conn:
    csr = conn.cursor()
    csr.execute("create user example password 'password-123'")
    conn.commit()

然后,我可以通过使用绑定参数的查询来选择有关该用户的信息:

with pg8000.dbapi.connect(**CONNECTION_INFO) as conn:
    csr = conn.cursor()
    csr.execute("select * from pg_user where usename = %s", ("example",))
    result = csr.fetchall()

但是,如果我尝试使用bind参数创建用户:

with pg8000.dbapi.connect(**CONNECTION_INFO) as conn:
    csr = conn.cursor()
    csr.execute("create user example password %s", ("password-123",))
    conn.commit()

请求失败,出现以下客户端错误:

DatabaseError: {'S': 'ERROR', 'V': 'ERROR', 'C': '42601', 'M': 'syntax error at or near "$1"', 'P': '30', 'F': 'scan.l', 'L': '1145', 'R': 'scanner_yyerror'}

服务器端错误:

2022-08-26 12:30:02.029 UTC [205] LOG:  statement: begin transaction
2022-08-26 12:30:02.029 UTC [205] ERROR:  syntax error at or near "$1" at character 30
2022-08-26 12:30:02.029 UTC [205] STATEMENT:  create user example password $1

如果我使用PG8000“本机”接口,也会发生同样的事情。
如果我切换到psycopg 2,我可以执行带有参数的create命令,但是服务器日志表明客户端进行了参数替换,并发送了一条文字SQL语句:

2022-08-26 12:30:55.317 UTC [206] LOG:  statement: BEGIN
2022-08-26 12:30:55.317 UTC [206] LOG:  statement: create user example2 password 'password-123'
2022-08-26 12:30:55.317 UTC [206] LOG:  statement: COMMIT
6jjcrrmo

6jjcrrmo1#

看来Postgres作为一个整体并不支持从预处理语句中调用JavaScript。我找不到任何关于这方面的权威文件:不在PREPARE的页面中,不在Overview of PostgreSQL Internals中,也不在客户端-服务器协议的描述中。然而,这很容易证明:

postgres=# prepare ddl_example ( varchar(255) ) as
postgres-# create user example password '$1';
ERROR:  syntax error at or near "create"
LINE 2: create user example password '$1';
        ^

在Google搜索的一些页面中,人们评论说,JavaScript不通过规划器,这是绑定变量的应用。这是有道理的,如果有人引用官方Postgres文档,请使用该链接回答。

j2cgzkjk

j2cgzkjk2#

您找到了答案,即您不能将参数与SQL语句一起使用,并且您正确地使用了PREPARE来测试该Assert。
让我补充一点,这是有记录的,虽然不一定在你会先看的地方:在documentation for PREPARE中。这告诉你哪些语句是允许的:
***statement***
任何SELECTINSERTUPDATEDELETEMERGEVALUES语句。

PostgreSQL中没有其他语句支持参数。

相关问题