如何防止SQL注入攻击 ------------------------------ SQL是指结构化查询语言,在关系型数据库中,使用SQL来操作数据库。 SQL注入攻击是伪造一些特殊请求字符串,来操作数据库。产生一些和程序员预期行为不一致的结果。 例如用户登录,通常有几种实现方法,假定设计用户认证表为包含三个字段,id, user_name, passwd, 表中含有三条记录:: 1, zhang abcdef 2, wang 666666 3, zhao 999999 如果某个用户登录,我们的python代码如下:: import sqlite3 class DatabaseConn: def __init__(self, sql_db): self.conn = sqlite3.connect(sql_db) self.conn.row_factory = sqlite3.Row self.c = self.conn.cursor() self.c.execute('''CREATE TABLE IF NOT EXISTS users (user_name text, passwd text)''') def query(self, username, passwd): """不安全的用法""" sql = "select * from users where user_name='{}' and passwd='{}'".format(username, passwd) print(sql) self.c.execute(sql) r = self.c.fetchone() print("row type:", type(r)) def query2(self, username, passwd): """安全用法,在传入参数时,使用?来格式化执行""" self.c.execute("select * from users where user_name=? and passwd=? ", [username, passwd]) r = self.c.fetchone() print("row type:", type(r)) def __del__(self): self.conn.close() conn = DatabaseConn('newdict.db') conn.query("zhang", "abcdef") conn.query("zhang", "123456") conn.query("zhang", "' or 1!='") conn.query2("zhang", "abcdef") conn.query2("zhang", "123456") conn.query2("zhang", "' or 1!='") 我们使用DatabaseConn对象来管理sqlite数据库连接,对象创建时连接数据库。 释放时关闭数据库。通过query,query2方法来对数据进行查询,我们对比一下 两个方法的差异。 如果我们使用query方法来查询用户账号和密码,如果是正确的密码,会找到记录 ,允许登录。如果是错误的密码,例如123456,找不到记录,不允许登录。 假设用户输入密码为带有单引号字符"' or 1!='", 也会执行找到记录, 因为sql语句会转换为:: select * from users where user_name='zhang' and passwd='' or 1!='' 这就是 sql 注入攻击,利用了我们代码实现的缺陷来对平台进行操作,甚至销毁数据库等等。 因此我们要防范数据库注入攻击。 使用 query2 方法可以避免这种sql注入攻击。它会把参数进行编译,只是当做一个参数, 而不会当做sql关键字来执行。