-1

我遇到了某种困境,我正在编写一个 JavaScript,它将数据从我的一个论坛发布到我运行 PHP 的服务器,然后决定输出一些不同的 JS,具体取决于发出请求的 URL。

我一直在向 JavaScript 的 XHR 添加一个 GET 参数,但该参数可能是伪造的,无法提供我正在寻找的安全性。

我正在寻找包含请求 URL 的超全局 PHP 变量(我已经查阅了手册,但我很难理解解释的含义)或任何其他检测 URL 的方法。

提前致谢...

4

3 回答 3

0

您可能正在寻找$_SERVER['HTTP_REFERRER']

http://php.net/manual/en/reserved.variables.server.php

请注意,这不是确定请求有效性的安全方法,但可以完成工作。

于 2013-11-13T12:45:40.780 回答
0

您在寻找什么样的安全性?防止用户伪造请求?他们可以通过伪造请求来实现什么?例如

  1. 他们可以自己搞乱网站布局吗?
  2. 他们可以访问不应被允许访问的数据吗?
  3. 他们可以写他们不应该被允许的数据吗?

如果答案是第一个,请不要理会它。无论如何,他们几乎可以在客户端做任何事情。如果您为伪造的请求提供不正确的数据,但允许他们以其他方式获取该数据,而不是什么危害?

您可以做的最好的事情是为您需要的对象制作一个restful api ,实现安全的用户处理,并检查每个请求对对象的正确用户授权。这样更干净,你不会搞砸的。

如果答案是第二个或第三个,那你就有问题了。一个简单的超全局变量是不够的。如果您实现某种身份验证(例如,像这样)和用户处理,您将已经拥有全局变量,因此您自己的变量将是多余的(并且不太复杂)。如果您有安全问题,我假设您已经以某种方式对用户进行了身份验证。您可以在 XHR 中检查用户是否经过身份验证(并授权访问内容),就像在“完整”请求中检查它一样。


从全局变量中猜测用户状态也会损害应用程序的可用性。考虑一下。

  1. 用户同时打开 2 个类似的页面,均包含此脚本。(选项卡 A 和选项卡 B)。
  2. 这两个请求都将给定的超全局设置为不同的值,因此只有第二个值被应用。(假设选项卡 A 将值设置为 A,然后选项卡 B 将值设置为 B)。
  3. 第一个选项卡中的脚本生成 XHR。这不是它所期望的。这是不好的。(由于超全局已经是 B,它返回用于选项卡 B 的内容)。

你能看出问题吗?


编辑:看到您的评论,我还不确定您的确切情况和需求是什么。我能够扣除一些东西:

假设您的域是good.com并且还有另一个域bad.com

你的场景:

  1. good.com/posthere您通过 JavaScript (to )发送一个 POST(不是 GET(?))请求
  2. 它返回一些 JavaScript
  3. 我不确定返回的 JavaScript 会发生什么,它可能以某种方式执行,但我不知道如何执行。

你想防止这种情况:

  1. 一个毫无戒心的受害者在 bad.com 上打开一个页面
  2. 上的页面向您的 URL ( )bad.com发出 POST 请求good.com/posthere
  3. 发回与发回同源请求相同的 JavaScript
  4. 浏览器在页面上执行该 javascriptbad.com
  5. 这会诱使用户认为他/她正在使用good.com,因为他/她能够与good.com

我对吗?我错了吗?我错过了什么吗?

恶意用户向您的站点发送请求与恶意站点诱骗毫无戒心的用户向您的站点发送请求之间存在很大差异。

例如,如果站点是恶意的,则浏览器中内置了某些安全措施,例如同源策略。如果用户是恶意的,他可以在客户端做任何他想做的事情,绕过浏览器提供的任何保护。他甚至不需要浏览器。他可以只使用cURL并在任何地方创建任何请求。

我将假设您有毫无戒心的用户意外访问bad.com而不是good.com.

那么该怎么办?

您可以做一些事情,我将列出一些可能适合您的情况。您可以将这些组合使用以提供更多保护层。

1. 不要通过网络发送 JavaScript!

虽然很诱人,但发送可嵌入资源是不知情的用户可能正在使用的每个现代(和不太现代)浏览器中内置的同源策略的一个例外。阅读我链接的文章,阅读整篇文章并仔细阅读:它解释了非常重要的事情。

同源策略限制从一个源加载的文档或脚本如何与另一个源的资源交互

这意味着它可以防止在bad.com站点上执行的 JavaScript 访问来自good.com. 正是你想要的。

不过也有一些例外。任何可嵌入的东西都可能被嵌入,然后以不同的方式访问。例如,可以使用 请求和执行 JavaScript(!)<script src="good.com/js">。这个标签可以由 JavaScript 创建。

当然,这只是一个GET请求,而不是一个POST,但我不确定POST请求是否有解决方法。

改为发送 JSON

发送安全的 JSON,用 JavaScript 解析它并根据 JSON 执行客户端的东西是一个很好的方法。

例如:

var json = '{"isWordfiltered":true,"otherProperty":5}', // this is the response from the server
    obj = JSON.parse(json);

if (obj.isWordfiltered) {
    alert("You wanted to send some bad words. Nobody likes bad words, and therefore nobody likes you!");
}

这需要您修改 JavaScript 代码。如果您不是程序员和/或不了解 JavaScript,这可能是不可取的。

2.检查HTTP Referer

HTTP referer(最初是referrer 的拼写错误)是一个HTTP 标头字段,用于标识链接到所请求资源的网页地址(即URI 或IRI)。通过检查referer,新网页可以看到请求的来源。

嘿,这听起来也像你想要的东西!您可以检查请求是来自您的页面还是来自他们的页面。推荐人不是来自您的域 = 被拒绝的请求。很简单。

您可以在 PHP 中通过访问$_SERVER['HTTP_REFERER'].

可以伪造推荐人,但这需要一定程度的用户同意(例如安装一些扩展程序),而好心的用户不会给予。他当然可以积极参与攻击,做任何事情,但我已经假设这不是你想要准备的情况。

在某些浏览器中可以禁用引用。在您的情况下,这是一个更大的问题。大多数用户都会启用引荐来源网址,但有时您会遇到出于“安全原因”禁用引荐来源网址的用户,或者浏览器默认禁用引荐来源网址(尽管这种情况非常罕见)。以某种方式提醒用户(我不建议该alert()方法,因为它丑陋且具有侵入性)可能是一个好主意,他需要启用引用者。

所以

  • 如果推荐人来自您的域,请接受请求。
  • 如果引用者为空。告诉用户他应该启用referer。
  • 如果推荐人不是来自您的域,请拒绝该请求。

告诉你想查看引用者的一个缺点是你告诉你检查它,因此攻击者可能能够利用这些信息来谋取利益。所以你可能想这样做(更简单)的方式:

  • 如果推荐人来自您的域,请接受请求。
  • 否则拒绝请求

3.(不要)使用 CSRF 令牌来防止伪造帖子

您可以实施 CSRF 令牌来防止某些伪造,但在您的情况下,这还不够,也不容易正确实施(在每个后续帖子上更改令牌等),所以我不建议将此作为解决方案你读过它。

4.(不要)使用会话令牌或cookie来查看用户是否访问过您的站点

请记住,如果您只检查用户已经访问过您的站点并在那里有活动会话的令牌,您可能会在$_SESSION$_COOKIE中设置一个标志(布尔值)并具有短暂的过期时间。如果用户最近还没有访问过您的网站,您可以拒绝对该 javascript 的请求。

尽管这似乎是一个不错的主意,但它很容易解决。例如通过一个不可见的<iframe>.


请记住,在实施第一个和/或第二个解决方案之后,您可能会退缩并认为您已经赢了,现在您的聊天是安全的。

事实并非如此。总是有新的攻击,不同类型的攻击等。

例如,如果攻击者是 Linux 术士,他可以在自己的网络服务器上从地狱变出黑暗代理,并使用它来伪造 HTTP 请求中的所有内容。像这样:

  1. 他将 javascript 更改为发布到bad.com/proxiedposthere.
  2. 服务器端的 php(或其他任何东西)以修改请求的 HTTP 标头(包括 REFERER)的方式编写,并将其转发到good.com/posthere.
  3. 您的服务器看到这是一个有效的请求,并向他的服务器返回一个有效的响应。
  4. 然后,他根据自己的喜好修改响应(例如,将响应中的所有 URL 切换为发布到他们的服务器而不是您的服务器等)。
  5. 他将响应返回给客户端的浏览器。

你不能完全阻止这种情况。您可以禁止代理服务器的 IP,但攻击者可以再次将其代理隐藏在其他代理后面。至无穷。

一个例子是笑话网站pornolize.com。它充当代理,并用淫秽内容切换网站文本中的许多内容。它还将链接切换为指向pornolize.com。这只是一个幼稚的笑话网站,但它是操纵响应的一个很好的例子。

所谓的网络代理的工作方式相同。他们(希望)不会以有害的方式操纵请求和响应,但他们也会切换链接。

于 2013-11-13T13:20:10.173 回答
0

您应该使用超全局 $_SERVER 变量。它包含您需要的一切。

这是您需要的示例:http ://webcheatsheet.com/php/get_current_page_url.php

于 2013-11-13T12:46:03.277 回答