web.py中防止sql注入
sql注入
sql注入是常见的安全漏洞。举例说明,web服务器为了验证用户名和密码,可能会执行下面这样一条sql查询:
SELECT * FROM user WHERE uid = 'name' AND passwd = '123'
其中uid和passwd是用户提交的输入字串。别有用心的使用者,在提交用户名和密码的时候,特意注入一些特殊字符,以达到攻击数据库的目的。比如,用户如果提交的uid为:name'# ,那么他使用任何passwd都可以通过用户名和密码验证。上面的sql查询语句会变成:
SELECT * FROM user WHERE uid = 'name'#' AND passwd = 'abc'
由于#在sql语句中起到注释的效果,那么上面的sql语句实际上执行的是:
SELECT * FROM user WHERE uid = 'name'
这就是sql注入攻击,在提交的字串中注入特殊字符,以达到改变sql语句执行效果的目的。
预防sql注入
在web.py中解决sql注入是比较简单的,那就是参数化查询。 下面列出几种,会被注入,和不会注入的写法,做对比。
# 会被注入的写法
query = "select * from user where uid='%s' and passwd='%s'" % (uid, passwd)
db.query(query)
# 不会被注入的写法
query = "select * from user where uid=$uid and passwd=$passwd"
p = {
'uid':uid,
'passwd':passwd
}
selected = db.query(query, p)
# 传入where条件字串的方法,会被注入
db.update('user', where="uid='%s' and passwd='%s'" % (uid, passwd), passwd='789')
# 传入参数的方法,不会被注入
db.where('passwd', uid=uid, passwd=passwd)
使用参数化查询,就可避免sql注入了。