只看:
(来源: https : //xkcd.com/327/ )
这个 SQL 做了什么:
Robert'); DROP TABLE STUDENTS; --
我知道'
和--
都是用于评论,但DROP
这个词是否也被评论,因为它是同一行的一部分?
它放下了学生桌。
学校计划中的原始代码可能看起来像
q = "INSERT INTO Students VALUES ('" + FNMName.Text + "', '" + LName.Text + "')";
这是将文本输入添加到查询中的天真方式, 非常糟糕 ,正如您将看到的那样。
在第一个名称,中间名称文本框FNMName.Text (这是Robert'); DROP TABLE STUDENTS; --
之后的值Robert'); DROP TABLE STUDENTS; --
)和姓氏文本框LName.Text (让我们称之为Derper
)与查询的其余部分连接,结果实际上是两个由语句终止符 (分号)分隔的查询 。第二个查询已注入第一个查询。当代码对数据库执行此查询时,它将如下所示
INSERT INTO Students VALUES ('Robert'); DROP TABLE Students; --', 'Derper')
用简单的英语粗略地翻译成两个查询:
使用名称值 “Robert” 向 Students 表添加新记录
和
删除学生表
超过第二个查询的所有内容都标记为注释 : --', 'Derper')
'
在学生的名字中 ' 不是评论,它是结束字符串分隔符 。由于学生的名字是一个字符串,因此在语法上需要完成假设的查询。注入攻击仅在它们注入的 SQL 查询产生有效 SQL时才起作用。
根据dan04的敏锐评论再次编辑
假设该名称用于变量$Name
。然后运行此查询:
INSERT INTO Students VALUES ( '$Name' )
代码错误地将用户提供的任何内容作为变量放置。你希望 SQL 是:
插入学生价值观(' Robert Tables` )
但聪明的用户可以提供他们想要的任何东西:
插入学生价值观(' Robert'); DROP TABLE 学生; - ')
你得到的是:
INSERT INTO Students VALUES ( 'Robert' ); DROP TABLE STUDENTS; --' )
--
只评论该行的其余部分。
正如其他人已经指出的那样, ');
关闭原始语句,然后是第二个语句。大多数框架(包括 PHP 等语言)到目前为止都有默认的安全设置,不允许在一个 SQL 字符串中使用多个语句。例如,在 PHP 中,您只能使用mysqli_multi_query
函数在一个 SQL 字符串中运行多个语句。
但是,您可以通过 SQL 注入操作现有的 SQL 语句,而无需添加第二个语句。假设你有一个登录系统,用这个简单的选择来检查用户名和密码:
$query="SELECT * FROM users WHERE username='" . $_REQUEST['user'] . "' and (password='".$_REQUEST['pass']."')";
$result=mysql_query($query);
如果您提供peter
作为用户名和secret
作为密码,则生成的 SQL 字符串将如下所示:
SELECT * FROM users WHERE username='peter' and (password='secret')
一切安好。现在假设您提供此字符串作为密码:
' OR '1'='1
然后生成的 SQL 字符串将是这样的:
SELECT * FROM users WHERE username='peter' and (password='' OR '1'='1')
这样您就可以在不知道密码的情况下登录任何帐户。因此,您不需要能够使用两个语句来使用 SQL 注入,但如果您能够提供多个语句,则可以执行更具破坏性的操作。