什么是SQL注入?
可能重复:
如何从“Bobby Tables”XKCD漫画工作SQL注入?
https://stackoverflow.com/search?q=sql+injection
有人可以解释SQL注入? 它是如何造成漏洞的? SQL注入点到底在哪里?
有人可以解释SQL注射器吗?
当您将某些内容插入到SQL查询string中时,会发生SQL注入,并且结果会以您不打算的方式修改查询语法。
它不一定是恶意的,它可能是一个意外。 但是意外的SQL注入更可能导致错误而不是漏洞。
有害的内容不一定来自用户,它可能是你的应用程序从任何来源获得的内容,甚至可以在代码中生成它自己。
它是如何造成漏洞的?
这可能会导致漏洞,因为攻击者可以将值发送到他们知道将插入到SQLstring中的应用程序。 通过非常聪明,他们可以操纵查询的结果,读取数据甚至改变他们不应该被允许的数据。
PHP中的示例:
$password = $_POST['password']; $id = $_POST['id']; $sql = "UPDATE Accounts SET PASSWORD = '$password' WHERE account_id = $id";
现在假设攻击者将POST请求参数设置为“ password=xyzzy
”和“ id=account_id
”,导致以下SQL:
UPDATE Accounts SET PASSWORD = 'xyzzy' WHERE account_id = account_id
虽然我期望$id
是一个整数,攻击者select了一个string,即列的名称。 当然, 每一行的条件都是真实的,所以攻击者只需为每个账户设置密码即可。 现在,攻击者可以login到任何人的帐户 – 包括特权用户。
SQL注入点到底在哪里?
这不是注入的SQL,而是插入(“注入”)到SQLstring中的内容,导致与我想要的不同types的查询。 我信任dynamic内容而不validation它,并盲目地执行生成的SQL查询。 这是麻烦开始的地方。
SQL注入是应用程序代码中的错误,通常不在数据库或数据库访问库或框架中。 SQL注入的补救措施遵循FIEO的做法:
- filterinput:validation内容是否符合您期望的格式,而不是假设。 例如,应用正则expression式,或使用像
intval()
函数那样的数据types强制转换。 - 转义输出:在这种情况下,“输出”是内容与SQLstring组合的地方。 在插入string时,通过使用转义字面引号字符的函数和可能是string边界的任何其他字符来避免不平衡的引号。
当应用程序的用户能够影响数据库查询的含义时,就会发生SQL注入。 当来自用户input的任意string连接在一起以创build提供给数据库的SQL时,通常会发生这种情况。 例如,假设我们有下面的代码(在PHP中,但对于任何语言都是如此),可以用来处理用户login。
$sql = "SELECT FROM users WHERE username='".$_GET['username']."' AND password='".$_GET['password']."'";
当用户input类似的东西时会造成危害
administrator'; --
…为用户名。 没有适当的编码,查询变成
SELECT * FROM users WHERE username='administrator'; -- AND password=''
这里的问题是'在用户名中closures用户名字段',然后开始一个SQL注释,导致数据库服务器忽略string的其余部分。 最终的结果是用户现在可以以pipe理员身份login,而不必知道密码。 SQL Inection也可以用来执行UPDATE,DELETE或DROP查询,真正损坏数据库。
SQL注入可以通过使用参数化查询,或应用您的语言/工具箱的转义函数(如PHP中的mysql_real_escape_string())来阻止。
一旦你理解了SQL注入,你会得到这个卡通背后的笑话。
网上有很多资源 – 只要谷歌它:
SQL注入是指那些被认为是数据的东西不被视为SQL代码。
例如,如果你这样做
mysql_query("SELECT * FROM posts WHERE postid=$postid");
通常它会给你一个给定的ID后,但假设$postid
设置为string10; DROP TABLE posts --
10; DROP TABLE posts --
; 突然之间,你发送的实际查询是
mysql_query("SELECT * FROM posts WHERE postid=10; DROP TABLE posts --");
这是一个相当大的问题,因为你会因为恶意用户而丢失整个post表 – 噢,亲爱的。
防止这种情况最简单的方法是使用预处理语句,例如通过PDO或MySQLi 。
PDO中的等效例子就是这样
$statement = $db->prepare('SELECT * FROM posts WHERE postid = :postid'); $statement->bindValue(':postid', $postid); $statement->execute();
这样做可以确保数据库系统知道$ postid被视为数据而不是代码,因此将被适当地处理。
这个问题已经在StackOverflow上多次被回答了,但是这是每个人都需要了解的一个重要的话题,所以我不打算去解决这个问题。
这里有一些关于这个话题的过去答案的链接:
- 什么是SQL注入?
- 如何从SQL注入保护此function?
- 参数是否足以防止Sql注入?
- SQL注入今天有风险吗?
我也在本月的MySQL会议上做了演讲,幻灯片在线:
- SQL注入神话与谬论
SQL注入是恶意用户将SQL放入input字段以尝试在服务器上运行SQL的地方。
我坚持的#1build议是使用参数化的存储过程,而不是在代码中构build原始SQL。
存储过程参数不会被执行,在大多数情况下都是安全的。
检查这些文章:
- SQL注入演练
- 防止SQL注入攻击
- SQL注入备忘单
在他们停止之前停止SQL注入攻击
CWE
CWE还有许多其他漏洞利用。
我发现这篇文章是关于SQL注入技术的一个非常好的阅读(链接是PDF): SQL Server应用程序中的高级SQL注入 。
尽pipe标题是“高级”,但即使对SQL注入没有太多的了解,它也是非常可读的。
要获得一些一般的背景,请查看关于SQL注入的维基百科文章 。
简而言之,SQL注入攻击可能使您容易受到数据库数据盗窃和破坏的所有威胁。 系统可以完成的具体细节取决于系统本身的细节。
无论何时您将用户的input传递给您的数据库,您都有一个潜在的注入点。 在这方面通常缺乏Web应用程序,因为新程序员通常不了解处理用户input的风险,Web应用程序受到你从未想过会find你的程序的非常聪明的人的攻击。
你会喜欢这个来自代码项目的文章; )
概要
- encryption敏感数据。
- 使用具有最less权限的帐户访问数据库。
- 使用具有所需特权的帐户安装数据库。
- 确保数据有效。
- 做一个代码审查,以检查是否存在二次攻击的可能性。
- 使用参数化查询。
- 使用存储过程。
- 重新validation存储过程中的数据。
- 确保错误消息不会泄漏应用程序或数据库的内部体系结构。
SQL注入的点是你的应用程序接受用户input的任何点。
这是否会成为Web应用程序的一个危险漏洞取决于此input是否稍后用作SQL查询的一部分,而不正确地检查其types并在必要时将其转义。
如果没有正确的转义,用户注入的某些SQL代码可能被SQL引擎作为SQL代码执行,而不是简单的string或值。