我的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
有没有办法删除引号,或者我是否应该解决从模式名称中删除非字母数字字符并将其称为一天的问题?后来看起来有点难看,但仍应该有用。
答案 0 :(得分:3)
要传递标识符,请使用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 :(得分: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)
答案 2 :(得分:0)
从psycopg2> = 2.7开始,psycopg2.sql可以用来组成动态语句,这也可以防止SQL注入。