我知道由于 .format,下面的代码片段容易受到 SQL 注入(inject)的影响,但我不知道为什么。有谁明白为什么这段代码容易受到攻击以及我会从哪里开始修复它?我知道这些代码片段使输入字段保持打开状态以通过 SQL 注入(inject)执行其他恶意命令,但不知道为什么
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)
最佳答案
使用您的第一个 SQL 语句的示例 SQL 注入(inject):
cursor.execute("insert into user(username, password) values('{0}', '{1}')".format(username, password))
如果
username
和 password
是 "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 不允许一次执行多个语句。尽管如此,可能还有其他注入(inject) SQL 的方法。 OWASP对该主题有很好的引用。
解决这个问题很容易,使用像这样的参数化查询:
cursor.execute("insert into user(username, password) values(?, ?)", (username, password))
使用
?
将占位符添加到查询中并且 db 引擎将正确地转义这些值以避免 SQL 注入(inject)。结果查询将是:insert into user(username, password) values('blah', 'blah''); drop table users; --')
终止
'
在 'blah\''
已正确逃脱。值(value)blah'); drop table users; --
将出现在插入记录的密码字段中。
关于Python SQLite3 SQL注入(inject)漏洞代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29528511/