gpt4 book ai didi

Python参数传递以防止sql注入(inject)。为什么这会出错?

转载 作者:太空宇宙 更新时间:2023-11-03 12:42:24 24 4
gpt4 key购买 nike

from django.db import connection, transaction

def pk_dt_catalog(p_CAT_ID,p_COMMONS_ID):

c1 = connection.cursor()
sql = "SELECT COMMONS_ID, CAT_ID, CAT_NAME
FROM DT_CATALOG"

sql = sql + " WHERE CAT_ID = %s
AND COMMONS_ID = %s "

param =(p_CAT_ID, p_COMMONS_ID)
c1.execute(sql, param)
return c1


>>> c = dt_catalog.pk_dt_catalog(513704,401)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "dt_catalog.py", line 24, in pk_dt_catalog
c1.execute(sql,(p_CAT_ID, p_COMMONS_ID,))
cx_Oracle.DatabaseError: ORA-01036: illegal variable name/number

最佳答案

在您的代码中,您使用的是 %s,这是 python 替换字符串语法,它期望替换值位于同一行,例如

sql = sql + " WHERE CAT_ID = %s
AND COMMONS_ID = %s " % (p_CAT_ID, p_COMMONS_ID)

但是,这(如前所述)并不是最好的方法,因为 (a) 它可能是一个 SQL 注入(inject)漏洞; (b) 由于每次调用都需要硬解析新的 SQL 语句,因此可能会导致数据库性能不佳。

相反,您应该使用 Oracle 绑定(bind)变量语法,例如:

c1 = connection.cursor()
sql = "SELECT COMMONS_ID, CAT_ID, CAT_NAME
FROM DT_CATALOG"

sql = sql + " WHERE CAT_ID = :foo
AND COMMONS_ID = :bar "

param = (p_CAT_ID, p_COMMONS_ID)
c1.execute(sql, param)
return c1

更多信息:http://guyharrison.squarespace.com/blog/2010/1/17/best-practices-with-python-and-oracle.html

上面的例子使用了位置绑定(bind),即第一个参数绑定(bind)到第一个绑定(bind)占位符,列表中的第二个参数绑定(bind)到第二个占位符。

更好的方法是使用字典按名称为特定绑定(bind)变量赋值。这在很难知道占位符添加到查询中的顺序时很有用,并使代码更易于阅读和维护:

c1 = connection.cursor()
sql = "SELECT COMMONS_ID, CAT_ID, CAT_NAME
FROM DT_CATALOG"

sql = sql + " WHERE CAT_ID = :foo
AND COMMONS_ID = :bar "

param = {"foo": p_CAT_ID, "bar": p_COMMONS_ID}
c1.execute(sql, param)
return c1

更多示例和教程:http://st-curriculum.oracle.com/obe/db/11g/r2/prod/appdev/opensrclang/pythonhol2010_db/python_db.htm

关于Python参数传递以防止sql注入(inject)。为什么这会出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5035580/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com