PHP Security / Databases and SQL / SQL Injection Tue, Jun 19. 2007
Trackbacks
Trackback specific URI for this entry
No Trackbacks
SQL injection attacks are extremely simple to defend against, but many applications are still vulnerable. Consider the following SQL statement:
SQL 注入攻击很容易就能防范,但是很多程序在这方面还是很脆弱的。 看下面的 SQL 语句:
This query is constructed with $_POST, which should immediately look
suspicious.
这个查询使用 $_POST 进行构造,这样一眼就能够看出问题。
Assume that this query is creating a new account. The user provides a desired username and an email address. The registration application generates a temporary password and emails it to the user to verify the email address. Imagine that the user enters the following as a username:
假设这个查询时用来创建新帐号用的。用户指定他们想要用户名和 email 地址。 然后注册程序生成一个临时密码并且发送给用户以验证 email 地址。 假设用户输入了一个这样的用户名;
bad_guy', 'mypass', ''), ('good_guy
This certainly doesn't look like a valid username, but with no data filtering in
place, the application can't tell. If a valid email address is given
(shiflett@php.net, for example), and 1234 is what the application generates
for the password, the SQL statement becomes the following:
这个用户名看起来肯定不是一个合法的用户名,但是如果没有适当的数据过滤,
程序是区分不出来的。如果给定了一个合法的 email 地址(例如 shiflett@php.net),
程序生成的密码是 1234,那么这个 SQL 语句就变成下面这个样子:
Rather than the intended action of creating a single account (good_guy) with a
valid email address, the application has been tricked into creating two accounts,
and the user supplied every detail of the bad_guy account.
本来预期的动作是创建一个有合法 email 地址的单一帐号(good_guy),
但是程序实际上被欺骗而创建了两个帐号,而且用户还指定了 bad_guy 帐号的所有信息。
While this particular example might not seem so harmful, it should be clear that worse things could happen once an attacker can make modifications to your SQL statements.
虽然这个特定的例子看起来没有那么大的危害,但是这说明了一旦攻击者能够修改你的 SQL 语句, 不定发生什么糟糕的事情呢。
For example, on the database you are using, it might be possible to send multiple queries to the database server in a single call. Thus, a user can potentially terminate the existing query with a semicolon and follow this with a query of the user's choosing.
例如,根据你用的数据库,很可能允许在一次调用中发送多个查询请求。 这样,用户就可能能够用一个分号终止当前的查询,然后紧跟着加入用户所选择的查询。
MySQL, until recently, does not allow multiple queries, so this particular risk is
mitigated. Newer versions of MySQL allow multiple queries, but the
corresponding PHP extension (ext/mysqli) requires that you use a separate
function if you want to send multiple queries (mysqli_multi_query() instead
of mysqli_query()). Only allowing a single query is safer, because it limits
what an attacker can potentially do.
到目前为止,MySQL 还不允许多重查询,所以这个特定的风险倒是不大。
MySQL 的新版支持多重查询,不过对应的 PHP 扩展(ext/mysqli)
要求你在希望进行多重查询的时候使用单独的函数(用 mysqli_multi_query() 替代 mysqli_query())。
因为单一查询能够限制攻击者可能做的事情,所以使用单一查询更加安全。
Protecting against SQL injection is easy:
防范 SQL 注入还是很简单的:
This cannot be overstressed. With good data filtering in place, most security concerns are mitigated, and some are practically eliminated.
这是绝对不能被越过的。如果在适当的地方有很好的数据过滤, 大多数安全隐患都能够减轻,甚至差不多都能够消除。
If your database allows it (MySQL does), put single quotes around all values in your SQL statements, regardless of the data type.
如果你的数据库支持,在 SQL 语句里给所有的值都加上单引号,不管是什么类型的数据。
Sometimes valid data can unintentionally interfere with the format of the
SQL statement itself. Use mysql_escape_string() or an escaping
function native to your particular database. If there isn't a specific one,
addslashes() is a good last resort.
有一些数据,虽然是合法的,但是可能会在无意中和 SQL 语句的格式产生冲突。
那么就使用 mysql_escape_string() 函数,或者你的数据库原生的转义函数进行数据转义。
如果没有特定的转义函数,addslashes() 是最后手段。
|
|
January '09 | |||||
| Su | Mo | Tu | We | Th | Fr | Sa |
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
© 2007 nullTao - 净空无道 - Blog | Main site | Contact me | RSS | Back to top
Powered by Serendipity | Design by Andreas Viklund | Serendipity Template by Carl