HTTP_ORIGIN 的安全性如何?

发布于 2024-10-10 06:14:49 字数 214 浏览 0 评论 0原文

我想查明来自第三方网站的传入 HTTP_REQUEST 调用是否来自我定义的域列表。

我知道可以使用HTTP_REFERER来查找第三方域在哪里,但它不够安全。人们可以欺骗它或使用 Telnet 来伪造它。

那么,HTTP_ORIGIN 怎么样?它是从所有浏览器发送的吗?安全吗?

另外,人们可以在 HTTP_REQUEST 调用中伪造 REMOTE_ADDR 吗?

I want to find out whether an incoming HTTP_REQUEST call from a third party website is coming from the list of domains that I defined.

I know that HTTP_REFERER can be used to find out where the third party domain is, but it is not secure enough. People can spoof it or use Telnet to fake it.

So, how about HTTP_ORIGIN? Is it sent from all browsers? Is it secure?

Also, can people fake the REMOTE_ADDR in a HTTP_REQUEST call?

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

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

发布评论

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

评论(7

眼泪淡了忧伤 2024-10-17 06:14:50

HTTP_ORIGIN 是一种防范 CSRF(跨站请求伪造)请求的方法。目前它仅由 Chrome 实现(截至 2011 年 11 月)。我测试了 Firefox 和 Opera,但都失败了。

它在请求标头中的名称是Origin。在我的 PHP 脚本的服务器上,我将其视为 $_SERVER 数组中的 HTTP_ORIGIN。仅在某些情况下,当需要针对 CSRF 的保护时才发送此标头(仅 POST 就足够了)。以下是所有请求的列表,无论是否设置:

https://wiki.mozilla.org/Security /Origin

  • 锚标记 - 否
  • 窗口导航 - 否
  • IMG - 否
  • iframe、嵌入、小程序 - 是
  • 表单(GET 和 POST) - 是
  • SCRIPT - 是
  • 样式表 - 否
  • 来自样式表的依赖加载 - 否
  • 重定向 - 是
  • XHR - 是

不幸的是,Origin 标头仅在 Chrome 中实现。它于 2010 年 1 月在 Google Chrome 博客上首次发布:

http://blog.chromium.org/2010/01/security-in-deep-new-security-features.html

通过 Origin 标头进行 CSRF 保护

Origin 标头是一项新的 HTML5 功能,可帮助您保护网站免受跨站请求伪造 (CSRF) 攻击。在 CSRF 攻击中,恶意网站(例如attacker.com)指示用户的浏览器向目标服务器(例如example.com)发送HTTP 请求,从而迷惑example.com 服务器执行某些操作。例如,如果 example.com 是网络邮件提供商,CSRF 攻击可能会欺骗 example.com 将电子邮件转发给攻击者。

Origin 标头通过识别哪个网站生成请求来帮助网站防御 CSRF 攻击。在上面的示例中,example.com 可以看到请求来自恶意网站,因为 Origin 标头包含值 http://攻击者.com。要将 Origin 标头用作 CSRF 防御,站点应仅在响应 (1) 缺少 Origin 标头或 (2) 具有带有白名单值的 Origin 标头的请求时修改状态。

我只是在我的 PHP 脚本中实现 CSRF 保护,我个人使用 Chrome,所以这对我来说已经足够了,我希望其他浏览器很快就能赶上 Chrome。

有趣的是,Mozilla 发明了该安全功能,因为您可以在其网站上阅读大量有关 Origin 标头的文档,但他们仍然没有时间实现它;-)

HTTP_ORIGIN 似乎只包含 protocoldomain,末尾没有斜杠:
“http://www.example.com” - 即使您从“http://www.example.com/myform/”提交表单。

PHP 脚本中针对 CSRF 的简单保护:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    if (isset($_SERVER['HTTP_ORIGIN'])) {
        $address = 'http://'.$_SERVER['SERVER_NAME'];
        if (strpos($address, $_SERVER['HTTP_ORIGIN']) !== 0) {
            exit('CSRF protection in POST request: detected invalid Origin header: '.$_SERVER['HTTP_ORIGIN']);
        }
    }
}

该脚本仍然可以升级以支持 80 以外的端口(Origin 包含与 80 不同的端口)、HTTPS 连接以及从不同子域(例如 sub.example.com)提交表单。 com => 向 www.example.com 发布请求)。

HTTP_ORIGIN is a way to protect against CSRF (Cross Site Request Forgery) requests. Currently it is implemented only by Chrome (as of Nov 2011). I tested Firefox and Opera, but they failed.

Its name in the request header is Origin. On the server in my PHP script I see it as HTTP_ORIGIN in the $_SERVER array. This header is sent only in some cases, when protection against CSRF is required (only POST should be sufficient). Here is list of all requests whether it is set or not:

https://wiki.mozilla.org/Security/Origin

  • Anchor tag - NO
  • Window navigation - NO
  • IMG - NO
  • iframe, embed, applet - YES
  • Form (GET and POST) - YES
  • SCRIPT - YES
  • stylesheets - NO
  • dependent loads from stylesheets - NO
  • Redirects - YES
  • XHR - YES

The Origin header is implemented only in Chrome, unfortunately. It was announced first in January 2010 on Google Chrome's blog:

http://blog.chromium.org/2010/01/security-in-depth-new-security-features.html

CSRF Protection via Origin Header

The Origin header is a new HTML5 feature that helps you defend your site against cross-site request forgery (CSRF) attacks. In a CSRF attack, a malicious web site, say attacker.com, instructs the user's browser to send an HTTP request to a target server, say example.com, that confuses the example.com server into performing some action. For example, if example.com is a webmail provider, the CSRF attack might trick example.com into forwarding an email message to the attacker.

The Origin header helps sites defend against CSRF attacks by identifying which web site generated the request. In the above example, example.com can see that the request came from the malicious web site because the Origin header contains the value http://attacker.com. To use the Origin header as a CSRF defense, a site should modify state only in response to requests that either (1) lack an Origin header or (2) have an Origin header with a white-listed value.

I am just implementing CSRF protection in my PHP script, I personally use Chrome, so that is sufficient for me, I hope other browsers will catch up with Chrome soon.

What is funny is that Mozilla invented that security feature, as you can read lots of documentation of that Origin header on its website, but they still didn't have time to implement it ;-)

HTTP_ORIGIN seems to contain only protocol and domain, without slash at the end:
"http://www.example.com" - even if you submit the form from "http://www.example.com/myform/".

A simple protection against CSRF in PHP script:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    if (isset($_SERVER['HTTP_ORIGIN'])) {
        $address = 'http://'.$_SERVER['SERVER_NAME'];
        if (strpos($address, $_SERVER['HTTP_ORIGIN']) !== 0) {
            exit('CSRF protection in POST request: detected invalid Origin header: '.$_SERVER['HTTP_ORIGIN']);
        }
    }
}

This script could still be upgraded to support PORT other than 80 (Origin contains the port when it's different than 80), HTTPS connections, and submitting the forms from different subdomains (ex. sub.example.com => posting request to www.example.com).

梦一生花开无言 2024-10-17 06:14:50

HTTP_ORIGIN 既不是由所有浏览器发送,也不安全。

浏览器发送的任何内容都不能被认为是安全的。

HTTP_ORIGIN is neither sent by all browsers nor is it secure.

Nothing sent by the browser can ever be considered safe.

甜警司 2024-10-17 06:14:50

这里的人们的想法都是错误的——“CORS”标准并不是为了让服务器不会被黑客攻击,即使它除了它所做的之外还有帮助。目的是让“浏览器”能够减轻违反同源策略的请求。如果客户端和服务器位于同一页面,则“客户端”可以决定是否允许该请求。

显然,通过让服务器参与决策,您可以帮助安全过程。

但它不能保护服务器免受未经授权的访问——这就是密码和 cookie 的用途。

客户端可以是(正如有人提到的)一个telnet工具,其中制作的每一个东西都是假的。

但是 Chrome 和 FF 等的卖点之一是,它们将通过不允许 Javascript 超出同源沙箱来帮助您,这意味着默认情况下唯一可能受到损害的是“攻击者自己的网站。或其他决定不安全的网站。

CORS 技术可以让您说——嘿,我希望用户能够通过他们使用的其他网站上的 javascript 来使用我的时髦服务。所以我要把这个网站添加到我的例外中。这意味着您正在帮助您的授权用户在该特定站点的浏览器安全性中找出漏洞。这意味着黑客可以利用一个漏洞。因此,您在设置服务时非常谨慎,对吗?

这意味着,默认情况下,任何未设置 CORS 的站点都可以免受来自兼容浏览器的跨站点脚本攻击(当然,排除错误和黑客攻击)。浏览器会询问该服务是否要参与源站点的 javascript,如果跨站点说“我对这个该死的站点一无所知”,那么浏览器的 javascript 引擎将关闭连接并转储数据。

综上所述,CORS 并不能帮助您确保安全。它可以帮助您在浏览器的能力上造成漏洞,从而使用户更加安全。但希望以一种托管的方式..并且仅适用于特定网站..

People here are thinking about this all wrong -- the 'CORS' standard isn't so the server doesn't get hacked, even if it helps that in addition to what it does. The purpose is to allow 'THE BROWSER' to have a way of easing up on requests that go against the same origin policy. If the client and the server are on the same page, then the 'CLIENT' can decide whether or not to allow the request.

Obviously by having the server participate in the decision you are helping in the security process.

But it won't protect the server from unauthorized access - that is what passwords and cookies are for.

The client can be (as someone mentioned) a telnet tool, where every single thing crafted is fake.

But one of Chrome's, and FF's, etc, selling points is that they will help you by not allowing Javascript to go outside of the same origin sandbox, which means the only thing by default that can be compromised is the stuff that is on the 'attackers' own website. Or other sites that decide to not be secure.

CORS is the technology that allows you to say -- hey, I want users to be able to consume my snazzy service from the javascript on this other site they use. So I'm gonna add this site to my exceptions. Which means you are helping your authorized users poke a hole in their browser security for that particular site. Which means a hole that a hacker can exploit. Thus the care with which you set up the service, right?

This means that any site that doesn't have CORS set up is by default secure from Cross Site Scripting from a compliant browser (barring bugs and hacks of course). The browser will ask if this service wants to participate in the origin site's javascript, and if the cross site says "I don't know nothing about this damn site", then the browser's javascript engine will close the connection and dump the data.

So just to summarize -- CORS doesn't help you make thing secure. It helps you make a hole in your browsers ability to make a user more secure. But hopefully in a managed way.. and only for particular sites..

铁轨上的流浪者 2024-10-17 06:14:50

HTTP 是一种纯文本协议。 ENTIRE 请求标头/正文结构可以伪造为您想要的任何内容。

HTTP is a plain-text protocol. The ENTIRE request header/body structure can be faked to say anything you want.

左岸枫 2024-10-17 06:14:50

HTTP 请求中的一切都可以伪造。

Everything in the HTTP request can be faked.

月光色 2024-10-17 06:14:50

升级:

function isOriginAllowed($incomingOrigin, $allowOrigin)
{
    $pattern = '/^http:\/\/([\w_-]+\.)*' . $allowOrigin . '$/';

    $allow = preg_match($pattern, $incomingOrigin);
    if ($allow)
    {
        return true;
    }
    else
    {
        return false;
    }
}

$incomingOrigin = array_key_exists('HTTP_ORIGIN', $_SERVER) ? $_SERVER['HTTP_ORIGIN'] : NULL;
    $allowOrigin    = $_SERVER['HTTP_HOST'];

    if ($incomingOrigin !== null && isOriginAllowed($incomingOrigin, $allowOrigin))
    {
        exit("CSRF protection in POST request: detected invalid Origin header: " . $incomingOrigin);
    }

示例:

  • http://media.mydomain.com TRUE
  • http://offline.mydomain.com TRUE
  • http:// domen1.mydomain.com TRUE
  • http: // domen_1.mydomain.com TRUE
  • http:// domen-1.mydomain.com TRUE
  • http:// ololomydomain.com FALSE
  • http:// mydomain.com TRUE
  • http:// pro.mydomain.com TRUE
  • http:// super.pro.mydomain.com TRUE
  • http://super.pro.fakemydomain.com FALSE
  • http://pro.fakemydomain.com FALSE

Upgraded:

function isOriginAllowed($incomingOrigin, $allowOrigin)
{
    $pattern = '/^http:\/\/([\w_-]+\.)*' . $allowOrigin . '$/';

    $allow = preg_match($pattern, $incomingOrigin);
    if ($allow)
    {
        return true;
    }
    else
    {
        return false;
    }
}

$incomingOrigin = array_key_exists('HTTP_ORIGIN', $_SERVER) ? $_SERVER['HTTP_ORIGIN'] : NULL;
    $allowOrigin    = $_SERVER['HTTP_HOST'];

    if ($incomingOrigin !== null && isOriginAllowed($incomingOrigin, $allowOrigin))
    {
        exit("CSRF protection in POST request: detected invalid Origin header: " . $incomingOrigin);
    }

Example:

  • http:// media.mydomain.com TRUE
  • http:// offline.mydomain.com TRUE
  • http:// domen1.mydomain.com TRUE
  • http:// domen_1.mydomain.com TRUE
  • http:// domen-1.mydomain.com TRUE
  • http:// ololomydomain.com FALSE
  • http:// mydomain.com TRUE
  • http:// pro.mydomain.com TRUE
  • http:// super.pro.mydomain.com TRUE
  • http:// super.pro.fakemydomain.com FALSE
  • http:// pro.fakemydomain.com FALSE
眼角的笑意。 2024-10-17 06:14:50

更新,截至 2021 年:

HTTP_ORIGIN 几乎得到所有浏览器的完全支持,请参阅:
https://developer.mozilla.org/en- US/docs/Web/HTTP/Headers/Origin#browser_compatibility

Update, as of 2021:

HTTP_ORIGIN is almost fully supported by all browsers, see:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin#browser_compatibility

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