Aym*_*man 4 python sql language-agnostic sqlite sql-injection
为了记录,我使用的是Python和SQLlite.我有一个生成我需要的SQL的工作函数,但它似乎不正确.
def daily(self, host=None, day=None):
sql = "SELECT * FROM daily WHERE 1"
if host:
sql += " AND host = '%s'" % (host,)
if day:
sql += " AND day = '%s'" % (day,)
return sql
Run Code Online (Sandbox Code Playgroud)
我可能需要稍后添加多个列和标准.
有更好的想法吗?
编辑: 看起来不正确的是我正在从Strings动态构建SQL.这通常不是最好的方法.SQL注入attacs,需要正确转义字符串.我不能使用占位符,因为某些值是None,并且不需要在WHERE子句条件中.
Mar*_*ers 12
您真的不想使用字符串格式来包含值.通过SQL参数将其保留到数据库API.
使用参数你:
由于SQLLite 支持命名的SQL参数,我将返回一个语句和一个带参数的字典:
def daily(self, host=None, day=None):
sql = "SELECT * FROM daily"
where = []
params = {}
if host is not None:
where.append("host = :host")
params['host'] = host
if day is not None:
where.append("day = :day")
params['day'] = day
if where:
sql = '{} WHERE {}'.format(sql, ' AND '.join(where))
return sql, params
Run Code Online (Sandbox Code Playgroud)
然后将两者传递给cursor.execute()
:
cursor.execute(*daily(host, day))
Run Code Online (Sandbox Code Playgroud)
SQL生成变得复杂快,你可能想看看SQLAlchemy的核心做代代替.
对于您的示例,您可以生成:
from sqlalchemy import Table, Column, Integer, String, Date, MetaData
metadata = MetaData()
daily = Table('daily', metadata,
Column('id', Integer, primary_key=True),
Column('host', String),
Column('day', Date),
)
from sqlalchemy.sql import select
def daily(self, host=None, day=None):
query = select([daily])
if host is not None:
query = query.where(daily.c.host == host)
if day is not None:
query = query.where(daily.c.day == day)
return query
Run Code Online (Sandbox Code Playgroud)
该query
对象可以应用其他过滤器,排序,分组,用作其他查询的子选择,加入并最终发送执行,此时SQLAlchemy将此变为适合您要连接的特定数据库的SQL.