使用psycopg cur.execute创建postgres模式

3
我的Python应用程序允许用户创建他们自己命名的模式。我需要一种保护应用程序免受SQL注入攻击的方法。
要执行的SQL语句如下:
CREATE SCHEMA schema_name AUTHORIZATION user_name;

Psycopg文档(通常)建议像这样传递参数以执行

conn = psycopg2.connect("dbname=test user=postgres")
cur = conn.cursor()
query = 'CREATE SCHEMA IF NOT EXISTS %s AUTHORIZATION %s;'
params = ('schema_name', 'user_name')
cur.execute(query, params)

但是这将导致一个带有单引号的查询失败:

CREATE SCHEMA 'schema_name' AUTHORIZATION 'user_name';
> fail

有没有办法去除引号,或者我只是去掉模式名称中的非字母数字字符就行了?后者看起来有点丑,但应该仍然有效。
3个回答

5

要传递标识符,请使用AsIs。但这会导致SQL注入的风险:

import psycopg2
from psycopg2.extensions import AsIs

conn = psycopg2.connect(database='cpn')
cursor = conn.cursor()
query = """CREATE SCHEMA %s AUTHORIZATION %s;"""
param = (AsIs('u1'), AsIs('u1; select * from user_table'))
print cursor.mogrify(query, param)

输出:

CREATE SCHEMA u1 AUTHORIZATION u1; select * from user_table;

1
这里有一个可能会有帮助的样板文件。我已经使用了环境变量,但您可以使用 .conf 或者其他任何您喜欢的方式。
将连接变量存储在 .env 文件中:
db_host = "localhost"
db_port = "5432"
db_database = "postgres"
db_user = "postgres"
db_password = "postgres"
db_schema = "schema2"

在您的app.py中加载参数并将它们分配给变量,然后在需要时使用这些变量:
import psychopg2
from dotenv import load_dotenv
import database

# Load your environment variables here:
load_dotenv()

db_host = os.environ["db_host"]
db_port = os.environ["db_port"]
db_database = os.environ["db_database"]
db_user = os.environ["db_user"]
db_password = os.environ["db_password"]
db_schema = os.environ["db_schema"]

# Build Connection:
connection = psycopg2.connect(host=db_host, 
                              port=db_port, 
                              database=db_database, 
                              user=db_user, 
                              password=db_password
                              )

# Build Query Strings:
CREATE_SCHEMA = f"CREATE SCHEMA IF NOT EXISTS {schema};"
CREATE_TABLE1 = f"CREATE TABLE IF NOT EXISTS {schema}.table1 (...);"
CREATE_TABLE2 = f"CREATE TABLE IF NOT EXISTS {schema}.table2 (...);"


# Create Schema and Tables:
with connection:
    with connection.cursor() as cursor:
        cursor.execute(CREATE_SCHEMA)
        cursor.execute(CREATE_TABLE1)
        cursor.execute(CREATE_TABLE2)

0

从psycopg2 >= 2.7开始,可以使用psycopg2.sql来组合动态语句,同时还可以防止SQL注入。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接