Python SQLite3 SQL注入漏洞代码

时间:2015-04-09 02:03:42

标签: python sql sqlite sql-injection

我知道下面的代码片段因为.format而容易受到SQL注入攻击,但我不知道为什么。有谁知道为什么这个代码容易受到攻击,我会在哪里开始修复它?我知道这些代码片段会打开输入字段以通过SQL注入执行其他恶意命令,但不知道为什么

cursor.execute("insert into user(username, password)"
         "  values('{0}', '{1}')".format(username, password))

handle[0].execute("insert into auditlog(userid, event)"
                  "  values({0}, ‘{1}')".format(handle[2],event))

audit((cursor, connection, 0), 
    "registeration error for {0}”.format(username))

 sql="""insert into activitylog(userid, activity, start, stop)
           values({0}, '{1}', '{2}', '{3}')
      """.format(handle[2], activity, start, stop)

3 个答案:

答案 0 :(得分:3)

使用第一个SQL语句的示例SQL注入:

cursor.execute("insert into user(username, password) values('{0}', '{1}')".format(username, password))

如果usernamepassword"blah",则生成的SQL语句为:

insert into user(username, password) values('blah', 'blah')

这个特定的陈述没有问题。

但是,如果用户能够输入password的值(可能来自HTML表单):

blah'); drop table user; --

生成的SQL语句将是:

insert into user(username, password) values('blah', 'blah'); drop table user; --

实际上是由分号分隔的3个语句:插入,删除表,然后是注释。一些数据库,例如Postgres将执行所有这些语句,导致用户表被删除。但是,尝试使用SQLite,SQLite似乎不允许一次执行多个语句。尽管如此,可能还有其他方法可以注入SQL。 OWASP对该主题有很好的参考。

修复此问题很简单,请使用参数化查询,如下所示:

cursor.execute("insert into user(username, password) values(?, ?)", (username, password))

使用?将占位符添加到查询中,db引擎将正确地转义这些值以避免SQL注入。结果查询将是:

insert into user(username, password) values('blah', 'blah''); drop table users; --')

'中的终止'blah\''已正确转义。值

blah'); drop table users; --

将出现在插入记录的密码字段中。

答案 1 :(得分:2)

来自the docs

  

通常,您的SQL操作需要使用Python中的值   变量。您不应该使用Python的字符串汇编查询   因为这样做是不安全的;它使你的程序   容易受到SQL注入攻击(请参阅http://xkcd.com/327/)   什么可能出错的幽默例子。)

     

相反,请使用DB-API的参数替换。放?作为一个   占位符,无论您想要使用哪个值,然后提供元组   value作为游标的execute()方法的第二个参数。   (其他数据库模块可能使用不同的占位符,例如%s或   :1。)例如:

# 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()

答案 2 :(得分:0)

每当使用字符串操作和外部用户提供的数据构造SQL语句时,您最多会遇到两种漏洞:

  1. 恶意意图,用户使用行分隔符,注释字符和SQL UPDATE或DELETE语句的某种组合键入值,这会对数据库产生负面影响(请参阅mhawke的回答)
  2. 用户输入合法文本的无辜意图,但它包含程序不期望的字符。一个例子是用户名为O'Reilly的人。当它被插入到字符串中时,备用撇号将使得结果SQL无效。