我的 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;
这是一个可能有帮助的样板。 我使用了环境变量,但您可以使用 .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)
从 psycopg2 >= 2.7 开始,psycopg2.sql 可用于编写动态语句,这也可以防止 SQL 注入。
要删除单引号:
query = query.as_string(conn)
query = query.replace("\'", "")
conn.execute(query)