Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How secure is HTTP_ORIGIN?

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?

like image 756
murvinlai Avatar asked Dec 30 '10 21:12

murvinlai


2 Answers

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).

like image 110
Czarek Tomczak Avatar answered Sep 21 '22 21:09

Czarek Tomczak


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

Nothing sent by the browser can ever be considered safe.

like image 32
ceejayoz Avatar answered Sep 21 '22 21:09

ceejayoz