我一直在阅读有关 SQL 注入攻击以及如何避免它们的信息,尽管我似乎永远无法使给定的“可怕”示例发挥作用,例如 查看这篇文章。
我在数据库中创建了一个 PHP 文件和一个表,通过 $_GET
传递了一个值,并尝试通过执行 bob'); 删除该表;掉表学生; --
但它不起作用。 PHP 自动转义 \'
并且查询有错误,没有造成任何损害。尝试复制诸如 AND WHERE 1=1
等登录“攻击”时出现同样的问题。
示例代码:
<?php
$id = $_GET['id'];
$sql = "INSERT INTO Users (Username) VALUES ($id)";
echo $sql;
mysql_query($sql) or die(mysql_error());
我会传递 sql.php?id=1);从用户中删除; --
那么,这是在 PHP3 或其他时代使用的一些过时的东西吗?现在,即使是新手也可以免受诸如魔术引号之类的东西的影响?
我在 Ubuntu 上使用 PHP5。
I've been reading about SQL injection attacks and how to avoid them, although I can never seem to make the "awful" examples given work, e.g. see this post.
I created a PHP file and a table in the database, had a value passed through $_GET
and tried to delete the table by doing bob'); drop table students; --
and it didn't work. PHP automatically escapes the \'
and the query has an error, no harm done. Same issue when trying to replicate login "attacks" like AND WHERE 1=1
etc.
example code:
<?php
$id = $_GET['id'];
$sql = "INSERT INTO Users (Username) VALUES ($id)";
echo $sql;
mysql_query($sql) or die(mysql_error());
And I'd pass sql.php?id=1); delete from Users; --
So is this some dated thing that used to apply in the days of PHP3 or something, and nowadays even novices are protected from things like magic quotes?
I'm using PHP5 on Ubuntu.
发布评论
评论(20)
恰恰相反。 魔术引号在 PHP5 中已被弃用,并将在 PHP 5.4 中被完全删除,因为它们给编程世界带来的混乱比它们带来的好处更多。检查魔术引号是否处于活动状态,并在必要时仔细转义任何 SQL 输入,仍然非常非常重要...不过没有理由感到难过,我们都经历过这种情况,无数魔术引号拯救了我不知情的屁股次 :)
关于魔术引号的 PHP 手册 解释了一切。
Quite the contrary. Magic quotes are deprecated in PHP5 and will be completely removed in PHP 5.4, as they brought more confusion to the programming world than they did good. Checking whether magic quotes are active, and escaping any SQL input scrupulously if necessary, is still very, very important... No reason to feel bad though, we've all been there, and my unknowing ass has been saved by magic quotes countless times :)
The PHP manual on magic quotes explains everything.
不,这仍然非常相关。
XSS 和 CSRF 也是如此。永远不要低估正确输入过滤的重要性。
No this is still very relevant.
As are XSS and CSRF. Never underestimate the importance of proper input filtering.
呵呵,在这种情况下,您可以通过
magic_quotes_gpc
设置为“on”。
你很快就会被搞砸。
Heh, you're saved in this case by having
magic_quotes_gpc
set to "on".You'll be screwed soon.
历史上最大的身份盗窃事件是在 2007 年通过利用 SQL 注入漏洞实现的:请参阅“”(ComputerWorld,2009 年 8 月 18 日)。
OWASP 2007 年报告注入攻击(其中 SQL 注入就是一个例子)继续是最常见的软件安全问题之一。
您还可以搜索最近的SQL注入新闻并查找每月都会报告许多病例。
然而,XKCD 漫画中的示例不一定是最常见的利用类型。通过在一个请求中执行第二条 SQL 语句来删除表可能不会让攻击者获得太多有价值的数据,这只是破坏行为。
另外,某些查询接口不允许多查询< /a> 无论如何都是默认的。也就是说,数据库客户端 API 仅执行给定 SQL 字符串的单个语句,而不管分号如何。这打败了漫画中显示的例子。
注意: PDO 的
query()
方法默认支持多查询。因此它容易受到XKCD式攻击。正如其他人指出的那样,更可能的风险是 SQL 注入会改变 SQL 表达式的逻辑,并将查询应用于除预期行之外的额外行。
例如:
当我发送参数
userid
设置为字符串123 OR userid=456
的请求时,会发生什么?我会重置我自己的密码(用户 ID 123)以及用户 ID 456 的密码。即使使用每个用户的盐对密码进行哈希处理也无法防止这种情况。现在我可以登录任一帐户。SQL 注入的实施方式有很多种。
The largest identity-theft in history was achieved in 2007 by exploiting an SQL injection vulnerability: see "SQL injection attacks led to Heartland, Hannaford breaches" (ComputerWorld, 8/18/2009).
OWASP reported in 2007 that injection attacks (of which SQL injection is one example) continue to be one of the most common software security problems.
You can also search for recent SQL injection News and find many cases reported every month.
However, the example in the XKCD cartoon isn't necessarily the most common type of exploit. Dropping a table by executing a second SQL statement in one request probably wouldn't gain the attacker much in the way of valuable data, it would just be vandalism.
Also, some query interfaces disallow multi-query by default anyway. That is, the database client API executes only a single statement given the SQL string, regardless of semicolons. This defeats the example shown in the cartoon.
note: PDO's
query()
method is known to support multi-query by default. So it is susceptible to the XKCD-style attack.As other folks have pointed out, the more likely risk is that an SQL injection will alter the logic of SQL expressions, and apply your query to extra rows besides those you intended.
For example:
What happens when I send a request with parameter
userid
set to the string123 OR userid=456
? I would reset my own password (userid 123) as well as the password of userid 456. Even hashing the password with a per-user salt wouldn't protect against this. Now I can log into either account.There are lots of ways SQL injection can be perpetrated.
魔术引号不考虑字符编码,因此容易受到基于 多字节 字符。
至于今天的风险,谷歌搜索会发现无数易受攻击的网站。已报告 Bugzilla 周围存在 SQL 注入漏洞9 月 10 日。所以,是的,网站仍然面临风险。他们应该是吗?这些工具是为了防止注入,所以不会。
Magic quotes don't take character encoding into account, and thus are vulnerable to attacks based on multi-byte characters.
As for it being a risk today, Google searches turn up countless vulnerable sites. An SQL Injection vulnerability was reported for Bugzilla around September 10. So, yes, sites are still at risk. Should they be? The tools are there to prevent injection, so no.
这种特定的攻击不起作用,因为 mysql_query 只会执行一条语句。
不过,我仍然可以滥用您的代码,例如,如果我将 id 安排为
SELECT password FROM Users WHERE Username='admin'
我可能有机会让您的系统暴露一些内部信息信息。基本上,如果您允许在 SQL 中进行未经过滤的输入,就会有一些非常有创意的方法来创建您不期望的数据,并公开您不想要的数据!
That particular attack doesn't work, as mysql_query will only execute a single statement.
I can still abuse your code though, e.g. if I arranged for id to be
SELECT password FROM Users WHERE Username='admin'
I might have a fighting chance of being able to get your system to expose some internal information.Basically, if you allow unfiltered input into your SQL, there will be some very creative ways of both creating data you didn't expect, and exposing data you didn't intend!
天哪.. SQL 注入不是风险,它是一个巨大的安全漏洞。它主要存在于 php 中,因为 API 使您想要将任何旧数据插入到 SQL 查询中。
当我看到用 PHP 或 ASP 编写的网站时,我就能闻到它们散发出的 SQL 注入向量的味道。人们尝试使用 mysql_real_escape_string() 和 intval() 来保护他们的 PHP 应用程序,并在其他语言中执行类似的操作。这是一个错误。这就像用 C 而不是 Java 或 Python 编码一样,在前者中,你犯一个错误就会死掉,但在后者中,只能存在语义缺陷。
我强烈建议人们使用 mysqli 和准备好的语句,或者任何其他参数化的东西,将文本替换为代码,然后解释它,恕我直言,这首先就是不好的做法。
另一方面,PHP 的魔术引号很愚蠢,值得庆幸的是,它已被弃用。它只会造成弊大于利。如果您依赖魔术引号,则意味着禁用魔术引号时您的应用程序将被拥有。同样,它可能会破坏其他不需要输入转义字符串的应用程序。
Oh my.. SQL Injection is not a risk, it is a gaping security hole. It mainly exists in php because the API makes you want to interpolate any old data into your SQL queries.
When I see a site written in PHP or ASP, I can just smell the SQL injection vectors that they reek of. People try to secure their PHP apps with
mysql_real_escape_string()
andintval()
and do similarly in other languages. This is a mistake. It's like coding in C instead of Java or Python, where in the former, you make one mistake and you're dead, but in the latter, only semantic flaws can exist.I strongly urge people to use either mysqli with prepared statements, or anything else that is parameterized, substituting text into code and then interpreting it is just bad practice in the first place IMHO.
On another note, PHP's magic quotes is just silly, and thankfully, deprecated. It can only cause more harm than good. If you rely on magic quotes, it means your app will be owned when magic quotes is disabled. Similarly, it may break other apps that don't expect escaped strings in inputs.
这是一个非常活跃的风险,魔术报价试图为您提供解决方案,但我更喜欢始终在关闭魔术报价的情况下进行开发。这样我就必须确保我自己确实逃脱了输入。谁知道在实际部署脚本的服务器上魔术引号是否会打开或关闭。
This is very much an active risk, magic quotes tries to give you a solution but I prefer to always develop with magic quotes off. This way I have to make sure I actually escape the inputs myself. Who knows if magic quotes will be on or off on the server where the script is actually deployed.
这仍然是一个大问题。您不能假设在您可能使用的每个 PHP 安装中都打开了 magic_quotes。
要查看魔术引号是否已打开并清除魔术引号中的混乱:
然后稍微清理一下您的语句:
等等。
事实上,如果您有以下条件,最好严格关闭
magic_quotes
有能力这样做。我希望这对你有帮助。
This is still a big problem. You can't assume that magic_quotes is turned on in every PHP installation you might use.
To see if magic qotes is turned on and clear out the mess from magic quotes:
Then cleaning your statements a little:
etc.
In fact, you're better off just strictly turning of
magic_quotes
if you have the ability to do so.I hope that helps you.
bobby 表示例不适用于 mysql 接口,因为它不会在一次调用中执行多个查询。 mysqli 接口容易受到多重查询攻击。 mysql 接口更容易受到特权提升攻击:
在您的表单中,我输入帐户:
admin
密码:' 或 1=1 --
这样您的典型登录 sql:从 user_name = '$admin' 且密码 = '$password' 的用户中选择 *
。或 导致此结果为真,然后让您登录。The bobby tables example will not work with the mysql interface because it doesn't do multiple queries in one call. The mysqli interface is vulnerable to the multiple query attack. The mysql interface is more vulnerable to the privilege boost attack:
In your form I type account:
admin
password:' or 1=1 --
so that your typical login sql:select * from users where user_name = '$admin' and password = '$password'
. The or causes this to be true and let's you log in.PHP不能做查询参数吗?如果可以(如果不能的话我会感到惊讶),这就是缓解所有 SQL 注入攻击的唯一解决方案。
Can't PHP do query parameters? If it can (as I'd be surprised if it didn't), that is the one solution which mitigates ALL SQL injection attacks.
正如我之前在 stackoverflow 上多次提到的那样,我是 PDO 的坚定支持者,只需停止使用老式 mysql,帮自己和您的客户一个大忙,学习 PDO(这真的很简单)并利用准备好的语句和绑定参数。即使您不需要准备好的语句性能,您仍然可以获得安全优势。
另外,如果魔术引号设置为打开,我建议您在客户面前崩溃整个应用程序。这只是为了保护愚人而惹恼聪明人而设计的资源的消耗。 (它比手动转义使用更多的CPU,因为它对所有内容进行编码,即使你不需要它)
As I've mentioned several times on stackoverflow before, I am a strong supporter of PDO, just stop using the old fashioned mysql, do yourself and your clients a big favor and learn PDO (it's really easy) and take advantage of prepared statements and bound parameters. Even if you do not need prepared statements performance wise, you still get the security benefits.
Also, I will recommend crashing your entire app in the clients face if magic quotes is set to on. It's just a drain on resources designed to protect the dumb and annoy the smart. (it uses more cpu than escaping manually, because it encodes everything, even when you don't need it)
有很多不同的方法可以执行 SQL 注入,并且有很多方法可以绕过基本的安全预防措施。
根据 OWASP,这些攻击已跻身前 10 位 Web 应用程序漏洞之列(排名第 2)。
欲了解更多信息,请参阅2007年十大注入缺陷 。
There are a lot of different ways to perform a SQL Injection and quite a lot of ways to bypass basic safety precautions.
Those attacks have been within the top 10 web application vulnerabilities (rank #2) according to OWASP.
For more information, please refer to Top 10 2007-Injection Flaws.
不,您越不担心 SQL 注入,您就越有可能受到它的攻击。
No, and the less you worry about SQL Injection, the more likely you are to get hit by it.
从网页传递给 SQL 查询的参数通常是数字 ID。例如,假设您有一个网址 http://foo.com/page.php?section= 34 ,其中的部分 ID 在如下查询中使用:
没有引号可以转义,就像您的示例中一样,您在 URL 中的数字后面添加的任何内容都将传递给查询...因此存在风险是真实的。
Parameters passed to sql queries from the web pages ofen tend to be numeric IDs. For example let's assume you have an url http://foo.com/page.php?section=34 from which the section ID is used in a query like this:
No quotes to escape like in your example and whatever you'll put after the number in the URL will be passed to the query... So thew risk is real.
最简单的经验法则是假设所有用户输入都可能受到污染。检查数据类型是否符合您的预期、变量是否在您预期的长度/大小范围内、文件是否具有您允许的大小和类型等。在致电重要管理员之前,可以保证对非外部数据进行其他检查-level 函数,进行检查 -
($userlevel != ADMIN)?die():important_function();
总有更大的鱼,或者更大的混蛋比你。避免对数据的假设,这样您就拥有了领先优势。
The simplest rule of thumb is to assume that all user
input
can be tainted. Check that data types are what you expect, variables are in the length/size ranges you were expecting, files are of the size and types you allow, etc. Other checks on non-external data can be warranted - before you call some important admin-level function, do a check -($userlevel != ADMIN)?die():important_function();
There's always a bigger fish, or somebody who's a bigger jerk than you. Avoid assumptions about data and you've got a head start.
还不到今天,但现在才 20:34 UTC
Guardian 作业数据库攻击展示了数据库安全的困难,2009 年 11 月 6 日
Guardian Jobs 网站黑客可能是一个SQL 注入而非“复杂”攻击,2009 年 10 月 27 日
Not today yet, but it's only 20:34 UTC
Guardian jobs database attack demonstrates difficulties of database security, 06 Nov 2009
Guardian Jobs website hack may have been an SQL injection and not a 'sophisticated' attack, 27 Oct 2009
每当从字符串构建 SQL 时,SQL 注入都是一个真正的危险。
我还发现尝试避免从字符串构建 SQL 是毫无意义的努力。迟早必须在运行时生成 SQL 的完整形式(而不仅仅是参数)。
Whenever building up SQL from strings, SQL injection is a real danger.
I have also discovered that trying to avoid building up SQL from strings is a pointless endeavor. Sooner or later the full form of your SQL (not just things that could be parameters) must be generated at runtime.
我必须开发一个无法让我禁用 magic_quotes 的服务器!我在每一页上都包含此内容,以消除魔术引号的影响,这样我就可以在不使用“双重转义”的情况下进行适当的转义。尽管我读到这篇文章就能尝到呕吐物的味道,但我还没有找到更好的解决方案。
I've have to develop for a server which has no way for me to disable magic_quotes! I include this on every page to undo the effects of magic quotes, so I can do proper escaping myself without \'double escaping\'. Even though I can taste vomit just from reading this, I haven't found a better solution.
根据OWASP 2017 Top 10,注入仍然是最常发生且最危险的攻击。
请记住,使用 SQL 注入,我们可以转储整个数据库,通过上传 Web shell 来控制 Web 服务器等。
As per OWASP 2017 Top 10, still Injection is the most happened and dangerous attack.
Just to remember, using SQL injection we can dump entire database, controlling web server by uploading web shell, etc.