使用 psycopg cur.execute 创建 postgres 模式
Creating postgres schemas using psycopg cur.execute
我的 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
有没有办法删除引号,或者我应该只接受从架构名称中删除非字母数字字符并收工?后者看起来有点丑,但应该仍然有效。
要传递标识符,请使用 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;
自 psycopg2 >= 2.7 起,psycopg2.sql 可用于编写动态语句,这也可防止 SQL 注入。
这是一个可能有用的样板文件。我使用了环境变量,但你可以使用 .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)
我的 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
有没有办法删除引号,或者我应该只接受从架构名称中删除非字母数字字符并收工?后者看起来有点丑,但应该仍然有效。
要传递标识符,请使用 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;
自 psycopg2 >= 2.7 起,psycopg2.sql 可用于编写动态语句,这也可防止 SQL 注入。
这是一个可能有用的样板文件。我使用了环境变量,但你可以使用 .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)