需要帮助理解 MySQL 注入
来自 http://www.tizag.com/mysqlTutorial/mysql-php- sql-injection.php 我得到:
SQL注入是指以下行为: 有人插入 MySQL 语句 无需您的数据库即可运行 知识。通常会发生注射 当您要求用户输入时,例如 他们的名字,而不是名字 给你一个MySQL语句,你 将在不知不觉中在您的数据库上运行。
我阅读了整篇文章,但我仍然有一些主要问题,无法理解它是什么以及如何完成。
在第一个例子中,他们实际上会看到什么?
据我了解,如果我实际上 echo $name ,则会看到所有名称,因为它总是“真实的”,我是对的吗?
我不明白的另一件事是 MySQL 注入问题是否可以通过 mysql_real_escape_string() 解决,必须有更多的内容。
我真正不明白的是 mysql_real_escape_string() 是为了解决这个问题而设计的,为什么这不是自动完成的,我的意思是有没有理由你必须每次添加 mysql_real_escape_string() ,是否有你应该使用的情况这就是为什么他们不让它自动化?
From http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php I got:
SQL injection refers to the act of
someone inserting a MySQL statement to
be run on your database without your
knowledge. Injection usually occurs
when you ask a user for input, like
their name, and instead of a name they
give you a MySQL statement that you
will unknowingly run on your database.
I read the whole article but I still have some major issues understand what it is and how can it be done.
In the first example, what will they actually see?
As far as I understood, if I actually echo $name, the will see all the names because it will always "be true" am I correct?
The other thing I don't understand is whether THE MySQL injection problem is solved with mysql_real_escape_string(), there has to be more to it.
What I really don't get is that mysql_real_escape_string() is made to solve that issue, why isn't this done automatically, I mean is there a reason you have to add every time mysql_real_escape_string(), is there cases when you should use it and that's why they don't make this automatic?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
MySQL不会自动转义,因为你自己构建查询字符串。例如:
您只需传递存储在 $query 中的原始字符串,该字符串对 SQL 注入是开放的。例如,如果 $name 是 [something" OR "1=1] 您的查询字符串最终为:
这将从用户表中返回每个用户。这就是为什么你需要转义值。但是,如果您使用 PDO,那么如果您使用绑定功能,它就会为您完成。这是一个两步过程,准备查询,然后将数据/变量“绑定”到占位符。在 PDO 中,您的查询字符串将如下所示:
然后,系统会自动为您转义内容。
MySQL won't escape automatically, because you build the query string yourself. For example:
You just pass the raw string stored in $query, which is open to SQL injection. For example, if $name is [something" OR "1=1] your query string ends up being:
That would return every user from the user table. Which is why you need to escape values. However, if you use PDO, it is done for you if you use the binding functionality. It's a 2 step process, preparing the querying, then "binding" the data/variables to the placeholders. In PDO, your query string would look something like this:
Then, things are automatically escaped for you.
Bobby Tables 对 SQL 注入的工作原理进行了很好的总结。最大的好处是它提供了多种语言的示例(C#、Java、Perl、PHP 等)。
对于 PHP,这在很大程度上取决于您访问数据库的方式。您可以受益于使用数据库提取层,例如参数化查询的 ADODB。
Bobby Tables has a great summary of how SQL injection works. Of much benefit is the examples it gives in several languages (C#, Java, Perl, PHP, etc.)
In the case of PHP, it depends a lot how you're accessing the database. You could benefit from using a database extraction layer such as ADODB which parameterizes queries.
在 Tizag 链接的第一个示例中,脚本作者希望查询最多获取一行。因此,考虑到每一行都将被获取,最可能的结果可能是返回的第一行的信息将被执行;由于被篡改的查询中没有
ORDER BY
子句,这可能是表中首先存储的用户,但是当ORDER BY
时,SQL 中当然没有定义顺序。 code> 子句丢失了,所以谁能说清楚。您可以说,只要表不为空,它就会获取有效用户的详细信息。我不确定“如果我回显
$name
”是什么意思;在代码中,$name
变量被赋予值"timmy"
。我猜他们会看到timmy
。如果您的意思是,如果您尝试回显通过查询获得的用户信息,他们会看到什么 - 好吧,这取决于您正在使用的代码。如果您循环访问结果集,并且他们使用 SQL 注入来获取您不希望他们获取的行,那么他们可能会看到所有行,包括您不希望他们看到的行。如果您的代码只是获取一行中的信息并对其进行操作,那么他们仍然会看到一行,尽管这可能是您不希望他们访问的一行。至于为什么 mysql_real_escape_string() 提供的功能不是自动的,那是因为它的自动功能需要计算机能够从您的 SQL 代码中计算出您想要执行的操作,而不是而不是只做你说要做的事。这既困难又坦率地不可取,因为没有人希望计算机事后猜测他们想要做什么(尤其是程序员)。
如果您希望能够摆脱使用 mysql_real_escape_string() 等,您可能需要考虑使用参数化查询,它允许您采取稍微不干涉的方法。不过,您仍然必须让计算机清楚查询的哪些部分是您想要转义的变量,因为这只是与计算机传达您想要发生的事情的重要组成部分。
In the first example at the Tizag link, the query looks like it's expected by the script author to fetch at most one row. So given that every row will be fetched, the most likely outcome is probably that the information for the first row returned will be acted upon; since there's no
ORDER BY
clause in the tampered-with query, this may be the user stored first in the table, but of course order isn't defined in SQL when theORDER BY
clause is missing, so who can say. What you can say is that as long as the table isn't empty, it will fetch the details of a valid user.I'm not sure what you mean by "if I echo
$name
"; the$name
variable is assigned the value"timmy"
in the code. So they would seetimmy
, I guess. If you mean, if you tried to echo to the user information obtained by the query, what would they see - well, it depends on the code you are using. If you are looping through a resultset and they used SQL injection to fetch rows you didn't expect them to fetch, then they will likely see all the rows, including rows you didn't intend them to see. If your code just fetches and acts on the information from one row, then they'll still see one row, though again it may be a row you didn't mean them to be able to reach.As for why the functionality offered by
mysql_real_escape_string()
isn't automatic, that's because for it to be automatic would rely on a computer being able to work out from your SQL code what you intended to do, rather than just do what you said to do. That is both difficult and frankly undesirable, because no-one wants a computer second-guessing what they want to do (particularly programmers).If you want to be able to get away from using
mysql_real_escape_string()
and the like, you might want to look at using parameterised queries, which allow you to take a slightly more hands-off approach. You still have to make it clear to the computer what parts of your query are variables you want escaped, though, because that's just part and parcel of communicating to the computer what you want to happen.在讨论 SQL 注入时,最常见的示例是“foo' OR 1 = 1”删除整个表或泄露密码。这些注入可以通过逃离字符串来阻止。
然而,还有一些更简单的注入,其中 mysql_real_escape_string() 无效。 例如,假设您有一个页面,用户可以在其中删除数据库中选定的条目。一个常见的实现是建立查询来删除基于 GET 或 POST 变量的条目,例如:
如您所见,用户可以轻松地将他们想要的任何“id”发布到此脚本,可能会删除整个表,即使 mysql_real_escape_string () 对字符串执行。可以利用同一漏洞来猜测哪个“id”属于管理员并篡改各处的值。据我所知,唯一的保护是从您能想到的每个可能的角度验证所有获取和发布参数。基本上,不只是进行表单验证 - 进行参数验证。
您会惊讶地发现如此简单的漏洞竟然如此容易地渗入您的代码中。
When discussing SQL injection, the most common example is "foo' OR 1 = 1" deleting an entire table or revealing passwords. These injections can be foiled by escaping the strings.
However, there are much simpler injections where mysql_real_escape_string() is ineffective. For example, say you have page where the user can delete selected entries from your database. A common implementation is to build up query to delete the entries based on GET or POST variables, e.g.:
As you can see, the user can easily post whatever "id" they want to this script, potentially deleting the entire table, even if mysql_real_escape_string() is performed on the string. This same vulnerability can be exploited to guess which "id" belongs to the administrator and tamper with values all over the place. As far as I know, the only protection is to validate ALL get and post parameters from every possible angle you can think of. Basically, don't just do form validation - do PARAMETER validation.
You'd be surprised how easy it is to let such a simple vulnerability slip into your code.
您是正确的,在第一个示例中,输入“错误”名称的人已被允许更改您正在执行的数据库查询,在这种情况下,他们已更改它以显示表中的所有行。
至于如何像使用子例程转义特殊字符一样容易防止这种情况,您需要了解可以在不同级别上理解字符串(或任何数据)。当您接受用户输入然后使用它构建数据库查询时,您希望数据库服务器将字符串解释为数据。然而,数据库服务器这样做的唯一原因是因为您使用单引号等特殊字符,因此它知道字符串在哪里开始和结束。 转义字符通过告诉数据库服务器(或解释它们的任何其他系统)不要解释特殊字符来工作字符作为特殊字符,但将它们解释为数据,就像字符串的其余部分一样。这样,如果字符串中存在这些特殊字符之一,则它的特殊功能将被忽略。
至于为什么这不是自动完成的?数据库服务器无法知道哪些数据可以信任,哪些数据不能信任。只有程序员知道,如果他们幸运的话!而且您不能只对所有数据执行此操作,因为这些特殊字符(例如单引号)的存在是有原因的 - 它们向数据库服务器传达含义 - 如果您转义所有这些字符,则无法传达含义他们的意义。这是计算机科学中的一个非常基本的概念——相同的信息可以在系统中的不同级别上进行解释,并且系统可能会使用该信息中的特殊数据模式来表示何时需要在不同级别上解释数据。
您可能会发现阅读抽象层的概念对于获得更基本的理解也很有用。
祝你好运!
You are correct, in the first example, the person who entered the "bad" name, has been allowed to alter the database query you are performing and in this case, they've altered it to show all rows in the table.
As far as how it can be as easy to prevent as using a subroutine to escape special characters, you need to understand that a string (or any data) can be understood on different levels. When you are accepting user input and then using it to build a database query, you want the database server to interpret the string as data. However the only reason the database server does this is because you use special characters like a single quote so it knows it knows where a string begins and ends. Escape Characters work by telling the database server (or any other system that interprets them) not to interpret special characters as special characters, but to interpret them as data, just like the rest of the string. That way if an one of those special characters is in your string, it's special function will just be ignored.
As for why this isn't done automatically? There is no way for the database server to know what data can be trusted and what data cannot. Only the programmer knows that, if they're lucky! And you can't just do it on all data because those special characters, (such as a single quote) are there for a reason - they convey meaning to the database server - if you escape all of them then there is no way to convey their meaning. This a really fundamental concept in computer science - that the same information can be interpreted on different levels in a system and a system might use special patterns of data within that information to denote when data needs to be interpreted at a different level.
You might find it useful to read up on the concept of abstraction layers too for a more fundamental understanding.
Good luck!
据我所知,在制作网站时,您必须始终假设最终用户是一个肮脏恶臭的威胁,想要破坏您的东西。因此,您应该始终使用 mysql_real_escape_string(); 、 htmlentities(); 等清理字符串。代码可以注入到您的表单数据中,该数据可以退出正在执行的操作,插入新代码,然后完全控制您的数据库,可能还可以控制您的文件结构,具体取决于它有权访问的内容。这意味着表、值、密码和整个数据库都可以被破坏或修改。
在某些情况下,您可能想自己注入代码,例如,如果您想创建一个可以将代码输入数据库的用户界面,该怎么办? (phpMyAdmin)。也许让它以某种方式自动转义代码会更好,然后如果你想要的话取消转义它..也许应该与 PHP/mySQL 的创建者讨论一些事情?
据我所知就这么多。我希望其他人能给你比这更多的见解。请记住始终清除表单和用户输入中的返回值。
As far as I know, when making websites you must always assume that the end user is a dirty stinking menace that wants to break your stuff. so you should always clean your strings with
mysql_real_escape_string();
,htmlentities();
and others. code can be injected into your form data that can exit what it was doing, insert new code and then have complete control of your database and possibly your file structures depending on what it has access to. this means that tables , values, passwords and your entire database can be destroyed or modified.There are instances where you may want to inject code yourself, for instance what if you wanted to make a user interface that could input code to your database. (ala phpMyAdmin) . maybe it would be nicer to have it automatically escape code somehow, and then un-escape it if you wanted it.. maybe something that should be discussed with the creators of PHP/mySQL?
This is as much as i know. I hope someone else can give you more insight than this. Just remember to always clean your returning values from forms and user input.
mysql_real_escape_string() 函数主要用于转义导致数据库错误的引号。您不能依赖此函数,因为清理非常重要,尤其是当您用户直接输入查询时。您可以参考此站点 https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
mysql_real_escape_string() function mainly used to escape quotes which results in database error.You couldn't depend on this function because sanitization I very important especially when you user input directly to query.You can refer this site https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet