PHP 中的单引号会自动转义吗?那么什么情况下需要清洗呢?

发布于 2024-11-15 16:32:33 字数 672 浏览 1 评论 0 原文

我正在阅读有关网络安全的内容,其中一个明显的主题是 SQL 注入。我正在尝试设置一个基本的 PHP 页面,我可以在其中执行 SQL 注入(它是本地服务器)。但是,我的代码(或服务器)似乎自动转义单引号。这是一个新标准还是我的服务器上激活了一个我不知道的设置?还需要清理输入吗?

这是我的服务器端代码的示例:

$foo = $_POST['foo'];
$sql = "SELECT * FROM bar WHERE foo='" . $foo . "'";

connectoTo("database");
query($sql);

其中 connectTo() 连接到数据库服务器并选择数据库,而 query() 是执行查询时使用的常用过程。从来没有清洁过什么。但是,当我发送

$_POST['foo'] = "' OR 1=1 #" 

PHP 页面时,它收到了

$_POST['foo'] = "\' OR 1=1 #"

So is foo 已经转义了吗?这与 $_GET 相同。

有什么想法吗?我们不再需要清理用户输入吗?

I'm reading up on web security and one obvious topic to cover is SQL injections. I'm trying to set up a basic PHP page where I can execute an SQL injection (it's a local server). However, it seems my code (or server) automatically escapes single quotes. Is this a new standard or is there a setting that's activated on my server that I don't know about? Is there a need to clean input any more?

Here's an example of my server side code:

$foo = $_POST['foo'];
$sql = "SELECT * FROM bar WHERE foo='" . $foo . "'";

connectoTo("database");
query($sql);

Where connectTo() connects to the database server and selects the database and query() is the usual procedure used when executing a query. No cleaning what so ever. However, when I'm sending

$_POST['foo'] = "' OR 1=1 #" 

the PHP page receives this as

$_POST['foo'] = "\' OR 1=1 #"

So is foo already escaped? This is the same with $_GET.

Any thoughts? Do we not need to clean user input any more?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相对绾红妆 2024-11-22 16:32:33

PHP 中有一个已失效的“功能”,可以自动转义 POST/GET 数据,称为 Magic Quotes。这个想法是为了防止常见类型的 SQL 注入发生。

实际上,您会得到混乱的数据,并且 SQL 注入仍然很有可能,具体取决于实现。 PHP 的开发人员很快意识到了这一点,并弃用了该功能,并且不鼓励使用它。

在正确的 PHP 安装中,绝对应该禁用此功能!如果您无权访问 PHP.ini 来设置 magic_quotes_gpc off,那么您可以将其放在代码顶部:

if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}

取自:http://www.php.net/manual/en/security.magicquotes.disabling.php

现在,解决您的 SQL 注入问题。你看,除了引用之外,还有更多事情需要担心。您没有指定正在使用哪个数据库,但这并不重要。避免注入问题的最佳方法是使用准备好的/参数化的查询。

准备好的查询是带有参数发送到服务器的查询,其值稍后发送。

INSERT INTO someTable (field1, field2) VALUES (:field1, :field2);

请注意 :field1:field2,因为它们是参数。当我执行此语句时,这些将被替换为正确的值。由于服务器正在执行此操作,因此不需要转义(和/或它发生在后台,具体取决于您正在使用的数据库层)。

在 PHP 中实现这一点的最简单方法是使用 PDO。如何使用 PDO 对于此框而言太长,因此我将向您指出教程的方向:

http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/

There is a dead "feature" in PHP that would automatically escape POST/GET data called Magic Quotes. The idea was to keep common types of SQL injection from happening.

In reality, you get jumbled data, and SQL injection was still very possible, depending on the implementation. The developers of PHP quickly realized this and deprecated the feature, and discouraged its use.

In a proper PHP installation, this should absolutely be disabled! If you do not have access to PHP.ini to set magic_quotes_gpc off, then you can put this at the top of your code:

if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}

Taken from: http://www.php.net/manual/en/security.magicquotes.disabling.php

Now, on to your SQL injection problem. You see, there are far more things to worry about than just quotes. You don't specify which database you are using, but it doesn't matter. The best way to avoid injection issues is by using prepared/paramterized queries.

Prepared queries are queries sent to the server with parameters, whose values are sent later.

INSERT INTO someTable (field1, field2) VALUES (:field1, :field2);

Note the :field1 and :field2, as they are parameters. When I execute this statement, those will be replaced with the proper values. Since the server is doing it, no escaping is necessary (and/or it happens in the background for you, depending on the DB layer you are using).

The easiest way to implement this in PHP is by utilizing PDO. How to use PDO is too long for this box, so I will point you in the direction of a tutorial:

http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/

一笔一画续写前缘 2024-11-22 16:32:33

在 php.ini 中禁用 magic_quote 并使用 PDO

Disable magic_quote in php.ini and use PDO.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文