只看: sql
(来源: https : //xkcd.com/327/ ) 数据库
此SQL的做用是: spa
Robert'); DROP TABLE STUDENTS; --
我知道'
和--
都是注释,可是DROP
这个词不是同一行的一部分吗? 翻译
它是这样工做的:假设管理员正在寻找学生的记录 code
Robert'); DROP TABLE STUDENTS; --
因为管理员账户具备较高的特权,所以能够从该账户删除表。 ip
从请求中检索用户名的代码是 element
如今查询将是这样的(以搜索student表) 字符串
String query="Select * from student where username='"+student_name+"'"; statement.executeQuery(query); //Rest of the code follows
结果查询变为 get
Select * from student where username='Robert'); DROP TABLE STUDENTS; --
因为未清理用户输入,所以上述查询已分为两部分 it
Select * from student where username='Robert'); DROP TABLE STUDENTS; --
双破折号(-)只会注释掉查询的其他部分。
这很危险,由于它会使密码验证无效(若是存在)
第一个将进行常规搜索。
若是该账户具备足够的特权,则第二个将删除该表格的学生(一般,学校管理员账户将运行此类查询,而且具备上述特权)。
它放下学生桌。
学校程序中的原始代码可能看起来像
q = "INSERT INTO Students VALUES ('" + FNMName.Text + "', '" + LName.Text + "')";
如您所见,这是将文本输入添加到查询中的简单方法,而且很是糟糕 。
在姓氏中的值以后,是中间名文本框FNMName.Text (这是Robert'); DROP TABLE STUDENTS; --
Robert'); DROP TABLE STUDENTS; --
Robert'); DROP TABLE STUDENTS; --
)和姓氏文本框LName.Text (称为Derper
)与其他查询串联在一块儿,结果其实是两个查询,由语句终止符 (分号)分隔。 第二个查询已注入到第一个查询中。 当代码对数据库执行此查询时,它将看起来像这样
INSERT INTO Students VALUES ('Robert'); DROP TABLE Students; --', 'Derper')
用简单的英语粗略地翻译成两个查询:
向“学生”表中添加一个名称为“ Robert”的新记录
和
删除学生表
第二个查询以后的全部内容都标记为注释 : --', 'Derper')
学生姓名中的'
不是注释,是结束字符串定界符 。 因为学生的名字是一个字符串,所以在语法上须要它来完成假设的查询。 注入攻击仅在其将有效查询注入结果的SQL查询时起做用。
根据dan04的敏锐评论从新编辑
');
结束查询,它不会开始注释。 而后,它删除了students表并注释了应该执行的其他查询。
SQL中的'
字符用于字符串常量。 在这种状况下,它用于结束字符串常量,而不用于注释。
数据库的做者可能作了一个
sql = "SELECT * FROM STUDENTS WHERE (STUDENT_NAME = '" + student_name + "') AND other stuff"; execute(sql);
若是student_name是给定的,则使用名称“ Robert”进行选择,而后删除表。 “-”部分将给定查询的其他部分更改成注释。