我正在尝试创建一个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
2条答案
按热度按时间6jjcrrmo1#
看来Postgres作为一个整体并不支持从预处理语句中调用JavaScript。我找不到任何关于这方面的权威文件:不在PREPARE的页面中,不在Overview of PostgreSQL Internals中,也不在客户端-服务器协议的描述中。然而,这很容易证明:
在Google搜索的一些页面中,人们评论说,JavaScript不通过规划器,这是绑定变量的应用。这是有道理的,如果有人引用官方Postgres文档,请使用该链接回答。
j2cgzkjk2#
您找到了答案,即您不能将参数与SQL语句一起使用,并且您正确地使用了
PREPARE
来测试该Assert。让我补充一点,这是有记录的,虽然不一定在你会先看的地方:在documentation for
PREPARE
中。这告诉你哪些语句是允许的:***statement***
任何
SELECT
、INSERT
、UPDATE
、DELETE
、MERGE
或VALUES
语句。PostgreSQL中没有其他语句支持参数。