看看:

(来源:https://xkcd.com/327/)

这个SQL做什么:

Robert'); DROP TABLE STUDENTS; --

我知道'和——都是用来评论的,但是DROP这个词不是也会被评论吗?因为它是同一行的一部分。


当前回答

假设你天真地写了一个学生创建方法,像这样:

void createStudent(String name) {
    database.execute("INSERT INTO students (name) VALUES ('" + name + "')");
}

有人输入名字罗伯特’);降表学生;--

在数据库上运行的是这个查询:

INSERT INTO students (name) VALUES ('Robert'); DROP TABLE STUDENTS --')

分号结束插入命令并开始另一个;——注释掉了该行的其余部分。DROP TABLE命令被执行…

这就是为什么绑定参数是一个好东西。

其他回答

单引号是字符串的开始和结束。分号是语句的结束。如果他们做这样的选择:

Select *
From Students
Where (Name = '<NameGetsInsertedHere>')

SQL将变成:

Select *
From Students
Where (Name = 'Robert'); DROP TABLE STUDENTS; --')
--             ^-------------------------------^

在某些系统上,select语句会先运行,然后是drop语句!信息是:不要嵌入值到你的SQL。而是使用参数!

');结束查询,不开始注释。然后它删除students表,并注释本该执行的其余查询。

不,'在SQL中不是注释,而是分隔符。

妈妈假设数据库程序员的请求是这样的:

INSERT INTO 'students' ('first_name', 'last_name') VALUES ('$firstName', '$lastName');

(例如)添加新的student,其中$xxx变量内容直接从HTML表单中取出,不检查格式也不转义特殊字符。

如果$firstName包含Robert');DROP TABLE student;——数据库程序将直接在DB上执行以下请求:

INSERT INTO 'students' ('first_name', 'last_name') VALUES ('Robert'); DROP TABLE students; --', 'XKCD');

ie。它会提前终止插入语句,执行黑客想要的任何恶意代码,然后注释掉可能存在的任何剩余代码。

嗯,我太慢了,我已经看到了8个答案在我之前的橙色带…:-)似乎是一个流行的话题。

假设你天真地写了一个学生创建方法,像这样:

void createStudent(String name) {
    database.execute("INSERT INTO students (name) VALUES ('" + name + "')");
}

有人输入名字罗伯特’);降表学生;--

在数据库上运行的是这个查询:

INSERT INTO students (name) VALUES ('Robert'); DROP TABLE STUDENTS --')

分号结束插入命令并开始另一个;——注释掉了该行的其余部分。DROP TABLE命令被执行…

这就是为什么绑定参数是一个好东西。

数据库的作者可能做了一个

sql = "SELECT * FROM STUDENTS WHERE (STUDENT_NAME = '" + student_name + "') AND other stuff";
execute(sql);

如果给出的是student_name,则使用名称“Robert”进行选择,然后删除表。“——”部分将给定查询的其余部分更改为注释。