Cal*_*ari 48 python sql postgresql sql-injection psycopg2
我有以下代码,使用pscyopg2:
sql = 'select %s from %s where utctime > %s and utctime < %s order by utctime asc;'
data = (dataItems, voyage, dateRangeLower, dateRangeUpper)
rows = cur.mogrify(sql, data)
Run Code Online (Sandbox Code Playgroud)
这输出:
select 'waterTemp, airTemp, utctime' from 'ss2012_t02' where utctime > '2012-05-03T17:01:35+00:00'::timestamptz and utctime < '2012-05-01T17:01:35+00:00'::timestamptz order by utctime asc;
Run Code Online (Sandbox Code Playgroud)
当我执行它时,它会失败 - 这是可以理解的,因为表名周围的引号是非法的.
有没有办法合法地将表名作为参数传递,或者我是否需要执行(显式警告)字符串连接,即:
voyage = 'ss2012_t02'
sql = 'select %s from ' + voyage + ' where utctime > %s and utctime < %s order by utctime asc;'
Run Code Online (Sandbox Code Playgroud)
为任何见解干杯.
Ant*_*aux 63
根据官方文件:
如果需要动态生成SQL查询(例如动态选择表名),可以使用psycopg2.sql模块提供的功能.
该sql模块是psycopg2版本2.7中的新增功能.它具有以下语法:
from psycopg2 import sql
cur.execute(
sql.SQL("insert into {} values (%s, %s)")
.format(sql.Identifier('my_table')),
[10, 20])
Run Code Online (Sandbox Code Playgroud)
更多信息:http://initd.org/psycopg/docs/sql.html#module-psycopg2.sql
[更新2017-03-24:AsIs不应该用于表示表或字段名称,而sql应使用新模块:https://stackoverflow.com/a/42980069/5285608 ]
另外,根据psycopg2文档:
警告:从不,从不,从不使用Python字符串连接(
+)或字符串参数插值(%)将变量传递给一个SQL查询字符串.甚至在枪口下也没有.
jcz*_*lew 30
根据这个答案你可以这样做:
import psycopg2
from psycopg2.extensions import AsIs
#Create your connection and cursor...
cursor.execute("SELECT * FROM %(table)s", {"table": AsIs("my_awesome_table")})
Run Code Online (Sandbox Code Playgroud)
Pea*_*oto 19
表名不能作为参数传递,但其他一切都可以.因此,表名应该在您的应用程序中进行硬编码(不要输入或使用程序之外的任何名称作为名称).您拥有的代码应该适用于此.
如果您有合理的理由获取外部表名,请确保您不允许用户直接输入它.也许可以传递一个索引来选择一个表,或者可以用其他方式查找表名.但是,你应该警惕这样做.这是有效的,因为周围的表名相对较少.找到一种验证表名的方法,你应该没问题.
可以做这样的事情,看看表名是否存在.这是参数化版本.只需确保执行此操作并在运行SQL代码之前验证输出.对此的部分想法来自这个答案.
SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' and table_name=%s LIMIT 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24771 次 |
| 最近记录: |