首先,我是数据库的新手,我昨天开始使用Python。
我开始玩sqlite3模块(之前我在Perl中通过DBI使用了一些Sqlite)
我在官方Python Sqlite文档here
上偶然发现了以下示例# Never do this -- insecure!
symbol = 'RHAT'
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
# Do this instead
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
print c.fetchone()
为什么第一个例子不安全而第二个没有?
让我们说我有一些存储文档的应用程序,用户可以按文档名称搜索数据库。
为此,我需要用户输入,然后使用关键字/ s
创建查询我不明白为什么一个元组现在应该更多"安全"那么一个字符串我的意思是在两种情况下用户都可以输入类似" xyz OR 1 = 1"显示每条记录。
我希望有人能够向我解释这个问题。我知道这对于有经验的人来说可能非常明显。
答案 0 :(得分:2)
参数不与简单字符串替换相同;他们将自己的价值直接提供给数据库而无需进一步解释:
>>> import sqlite3
>>> db=sqlite3.connect(":memory:")
>>> db.execute("CREATE TABLE t(x)")
>>> db.execute("INSERT INTO t VALUES('x'),('secret')")
>>> db.execute("SELECT * FROM t WHERE x = '%s'" % ("x' OR 1=1--",)).fetchall()
[(u'x',), (u'secret',)]
>>> db.execute("SELECT * FROM t WHERE x = ?", ("x' OR 1=1--",)).fetchall()
[]
使用参数,您可以获得与为所有特殊字符(在本例中为WHERE x = 'x'' OR 1=1--'
)正确引用该值的效果相同的效果。