5

我的网站有页眉、页脚和主要内容。如果用户未登录,则对于主要内容,可能会显示登录表单而不是实际内容。

在该登录表单上,我$_SERVER['REQUEST_URI']在会话变量中写入了$_SESSION['redirect']

我的登录表单后处理程序,它将登录用户,将在成功登录后将用户发送到此链接header('location: http://myserver.com'.$_SESSION['redirect']);

因此,如果我转到myserver.com/somesite.php?somevar=10它会在您登录时显示正确的站点。否则它将显示登录表单,但是浏览器地址栏中的 URL 仍然显示myserver.com/somesite.php?somevar=10 Then you enter your credentials and you are redirected to myserver.com/somesite.php?somevar=10,这将然后 - 因为您现在已登录 - 完全显示。

我不将该REQUEST_URI值用于表单操作或用作链接 href。

此外,$_GET我使用的任何变量我首先检查它们是否匹配正则表达式(通常变量将是一个sha1字符串或随机生成的数字和字母字符串,没有特殊字符),如果 get 变量,我总是使用准备好的语句用于数据库查询。

我的问题是是否有任何安全问题?有什么方法可以利用这个,在 url 中输入恶意内容,然后将其发送给另一个用户,例如......?我应该在这个过程中以某种方式逃避某些东西吗?

4

4 回答 4

3

关键规则是你总是检查你的输入/输出,看看你能控制什么,不能控制什么(因此,什么可以由用户控制)。在此基础上,您应用安全/消毒措施。

如果我正确理解您的场景,您将显示该页面,除非用户未登录。在这种情况下,您会显示一个登录框,并在成功登录后将用户发送回他尝试使用的页面访问$_SERVER['request_uri'](存储在会话中)。

所以用户显然可以控制这个变量,他可以用一些难看的字符浏览到你的页面。因此,您需要对其进行消毒。正如@Wayne 在评论中提到的那样,例如,用户可以遍历您的目录树。

因此,就像您的$_GET变量一样,您也需要对其进行清理$_SERVER['request_uri']。有很多方法可以做到这一点。最安全的方法可以说是在使用或类似的东西request_uri进行消毒之后检查它是否是现有页面。请注意,特殊的目录遍历方法(html_entities()例如../和 )可能会通过传统的清理方法(例如前面提到的)//./html_entities()

并从字面上回答: 我是否应该在此过程中以某种方式逃避某些事情? - 是的,一切,在每个过程的开始。

------ 编辑@ 12-12-2013 -----

(评论的答案太长,所以我将在这里解释用户如何使用目录遍历,包括潜在的危险情况)

来自 PHP 手册:

$_SERVER['REQUEST_URI']: The URI which was given in order to access this page;
                         for instance, '/index.html'.

所以,假设我想去yourdomain.com/posts/post.php?../../../ssh你的 web 应用程序会注意到我没有登录,存储post.php?../../../ssh在会话中并处理登录,然后它把我发回 url。由于../../../ssh部分原因,我不会被发送到 post.php,而是被发送到您的服务器上的一个目录,该目录位于ssh您的 webroot 之下。为方便起见,您已将 SSH 密钥存储在那里。这似乎是安全的,因为它在 webroot 之外,任何 web 用户都不能访问它。然而,我可以因为我巧妙地添加到您的网址。

虽然这有点牵强,但正确配置的 http-server、chrooting 环境等会阻止这种情况,但这个示例确实向您展示,如果您允许添加这些字符,它们可能会使用户访问他们不应该访问的位置.

根据您的实现,盲目添加$_SERVER['request_uri'] 也可能意味着将不需要的内容添加到会话中,如果您将该会话存储在数据库中,它也会被添加到数据库中。我并不是最新的(不)安全的 PHP,但我可以想象这允许打破会话变量并可能将内容注入您的数据库。

尽管并非一切皆有可能,而且该示例可能并非真正可行,但最好避免这种行为,也不那么难。

-- 细思极恐:也许这些header('location'...东西是不安全的,但是这个:这个 PHP 重定向不安全吗?表明它不是真的。然而,就像那里的评论者所说:打字并不难urlencode()

于 2013-12-11T22:30:43.373 回答
1

将任何东西放在网上都有许多安全问题。在发布/获取请求中具有可识别的模式是一个问题,但这取决于很多因素,主要是......用户可以从弄乱您的网站中得到什么,以及您对网站用户的恶意意图负有多大责任。

您应该做一些研究来清理您的输入,使用会话令牌将是您可以做的第一件事,以确保您的登录脚本的流量实际上是由您网站上的用户生成的。这两种常见做法是防止 sql 注入和跨站点脚本攻击的第一步。通过良好的数据库设计和良好的代码设计,确保您的数据受到保护的适当步骤。

我最喜欢的技术之一是将我的应用程序配置为使用自定义 http 标头,并且任何从 Super Global 检查接收数据的脚本以确保将自定义标头作为我的安全组件正确提供。任何黑客都可以轻松查看和嗅探这些标头,但许多恶意攻击首先由脚本执行,而这只是一个易于部署的步骤,使您成为此类攻击的更难目标。

一个关于强化基于 php 的网站的快速谷歌搜索出现了这篇文章,其中有一些很好的提示:http ://www.noupe.com/php/php-security-tips.html

于 2013-03-05T02:28:37.997 回答
1

你永远不会 100% 安全。你可以看看OWASP 前十名。这些是主要的安全问题。

我认为您应该在 $_SESSION 中与每个用户关联一个令牌(随机数),而不是$_SERVER['REQUEST_URI']. 您可以通过 GET 传递 REQUEST_URI 并通过 POST 传递令牌(在隐藏的输入中),然后对其进行验证。如果此 URI 需要用户登录,请确保收到的用户令牌等于会话用户令牌。

于 2013-12-16T14:41:25.983 回答
1

您正在重定向到一个相对 URL,这很好,因为这意味着攻击者无法使用诸如此类的方法来使用会话固定来毒化会话变量,并重定向到他们自己的域。您不应对此值进行任何编码,因为它是原始 URI 的直接副本,并且也是您希望将用户重定向到的确切 URI。不过,您应该检查您正在使用的 PHP 版本是否容易受到标头注入的影响。看来它已在 PHP 中修复

4.4.2 和 5.1.2 此功能现在可防止一次发送多个标头,以防止标头注入攻击。

关于路径遍历的其他答案在这里不应该是一个问题,因为没有比用户直接在他们的地址栏中输入路径的额外风险。使用标头重定向它们的事实location不会增加这种风险。但是,您应该确保您的服务器平台不会受到攻击,但请记住,这与您的重定向方法无关,因为它location只是告诉客户端加载另一个地址。

确保在设置 headerexit后调用,否则攻击者将能够通过查看原始 HTTP 响应来查看您的页面内容:-

<html>
<?php
/* This will give an error. Note the output
 * above, which is before the header() call */
header('Location: http://www.example.com/');
exit;
?>

我无法评论您的网站可能存在的每个漏洞,但本质上您建议进行重定向的方式应该是安全的。但是,您应该确保您的站点只能通过 HTTPS 访问,这将加密连接并确保它免受MITM攻击。您还应该在会话 cookie 上设置安全标志,以确保它不会通过非 HTTPS 连接泄露。

于 2013-12-16T22:39:27.217 回答