什么是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注入,你会得到这个卡通背后的笑话。

网上有很多资源 – 只要谷歌它:

http://en.wikipedia.org/wiki/SQL_Injection是一个很好的起点。;

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或值。