python mysql参数化查询防sql注入

一、写法

cursor.execute('insert into user (name,password) value (?,?)',(name,password))

  或者

cursor.execute('insert into user (name,password) value (%s,%s)',(name,password))

  %s与?都可以作为sql语句的占位符,它们作为占位符的功能是没有区别的,mysql.connector用 %s 作为占位符;pymysql用 ? 作为占位符。但是注意不要写成

cursor.execute('insert into user (name,password) value (?,?)'%(name,password))

  这种写法是直接将参数拼接到sql语句中,这样数据库就容易被sql注入攻击,比如

cursor.execute('select * from user where user=%s and password=%s'%(name,password))

  要是name和password都等于'a or 1=1',那么这个语句会把整个user表都查询出来

二、原理

  python并不支持mysql预编译语句,其实“参数化”是在MySQLdb中通过转义字符串然后直接将它们插入到查询中而不是使用MYSQL_STMT API来完成的。因此,unicode字符串必须经过两个中间表示(编码字符串,转义编码字符串)才能被数据库接收。

  也就是说,我们传入的参数并不是直接拼接到sql语句中,而是经过了字符转换,因此参数化查询可以有效防止sql注入