12

I am trying to connect to an external web socket server, which is not run by myself. I would like to connect to it from a localhost javascript file, therefore the origin header has null value.

I understand that this is a measure against cross-site forgery. However, since I am on localhost, I should be able to fake this, by getting Chrome to send a custom Origin header.

Is it possible? (if I need an extension, that is fine)

If not, what is my best option to achieve the above? Thank you.

David Frank
  • 5,918
  • 8
  • 28
  • 43

4 Answers4

20

Web pages cannot change the Origin header, but extensions can modify the request headers via the chrome.webRequest API. But ws:// and wss:// are not supported by this API, so this doesn't help unless the server also supports other means of communication via http(s) (e.g. long-polling).

There is still a solution though: Simply load a (known) web page at the desired origin in an iframe (e.g. https://example.com/favicon.ico or https://example.com/robots.txt) and use a content script to open the WebSocket from there.

Rob W
  • 341,306
  • 83
  • 791
  • 678
11

The Origin header is one of the headers that are set automatically by the user agent (as part of the browser implementation), and cannot be altered programatically or through extensions. This makes sense because web service providers cannot allow random connections from localhosts.

You can connect to an external WebSocket only if you do it from a host explicitly accepted by the web service provider. Many headers cannot be trusted (because they can be overridden), but this is not the case with Origin as it offers security not only for users, but also for service providers against unwanted connections.

adriann
  • 396
  • 2
  • 12
  • 3
    There is something I do not understand. How can the service make sure that I am not providing a fake origin? Why cannot I go into Chrome's source code and modify the restricting part or build my own browser that has no such restriction? I guess, there is a design principle that does not let me do it, but what is it? – David Frank May 17 '15 at 21:04
  • 1
    Ok, I checked the RFC, and it says: "The intent is not to prevent non-browsers from establishing connections but rather to ensure that trusted browsers under the control of potentially malicious JavaScript cannot fake a WebSocket handshake." Based on this I think, the origin header is just means to prevent a malicious website from connecting to a third-party web socket from a user's browser without them knowing it. – David Frank May 17 '15 at 21:18
  • 1
    The service provider in this case only validates the Origin header and trusts it to be uncompromised. Of couse, in theory you could tamper with the browser code or create a tool for custom HTTP requests, but this is not trivial and not recommended. Yes, the Origin header aims first at user security. It is more or less the same as with crawling websites that explicitly forbid this in a robots.txt file (no one can guarantee it will be honored). – adriann May 17 '15 at 21:46
  • The service cannot make sure you are providing a legit Origin, but it is sure that OTHER users are not been tricked by your website into connecting a third party that requires the right origin. – vtortola May 18 '15 at 10:59
  • 2
    @DavidFrank Yes you can create a browser that does this, but how do you force other people to use your modified browser? If you are the only one using your insecure browser you are only hurting yourself. We trust Apple/Google/Mozilla to provide us with browsers that prevent modifying the Origin header. – baueric Aug 09 '18 at 19:50
2

As far as I know this will not be possible, it would break the security guards against CSRF in Chrome.

If you were able to do that the whole concept of XHR would fall apart.

Here is an Extension you can use to manipulate header on the fly, but so far I have not been able to get it to manipulate socket headers.

Look here if you want to read more about this.

But this doesn't stop you from implementing your own client (in place of chrome) where you can literally send whatever headers you want, not sure if this helps you, sorry.

Community
  • 1
  • 1
tato
  • 59
  • 5
  • 2
    Security guards against CSRF are usually in place to protect the user. In this case, however, my intention (as the user) is to add an exception to chrome to weaken this protection. Since chrome creates and sends the http request, in theory I should be able to override any headers (probably using an extension). – David Frank May 17 '15 at 20:04
  • I'll add an extension I found that allows header modification. I was able to modify the headers but not yet when using sockets for some reason. – tato May 17 '15 at 20:27
1

It depends how you want to use your chrome browser. Since you mention localhost I assume you develop and will use this for some kind of scraping. I suggest that you explore Chrome DevTools Protocol which will render (almost) any kind of protection useless because you use a real browser. CORS, Origin, Cookie or any arbitrary header value will be under your control, and you can send a custom header for xhr/websocket request(s). If you want to manipulate in a more advanced way you can use Network.continueInterceptedRequest. You might only want to start chrome using parameters like "--disable-web-security, --disable-xss-auditor, --disable-client-side-phishing-detection, --allow-insecure-localhost" more about such options at peter.sh. However, the last option require a plugin in order to spoof origin header so I recommend the first option.

Gillsoft AB
  • 4,185
  • 2
  • 19
  • 35