Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meteor apps have insecure CORS configuration on /sockjs/info path by default #8317

Closed
craigdrayton opened this issue Feb 6, 2017 · 19 comments

Comments

@craigdrayton
Copy link

I recently conducted a vulnerability scan of my Meteor app. The scan reported an insecure CORS configuration, where the '/sockjs/info' path returns insecure header "Access-Control-Allow-Origin: *".

See this related issue in SockJS: sockjs/sockjs-node#217

Is there a workaround for resolving this vulnerability in Meteor or my application code / configuration?

Even if the vulnerability is not a true security risk, it is important that I can get a clean bill of health from the vulnerability scan.

@stubailo
Copy link
Contributor

stubailo commented Feb 6, 2017

Even if the vulnerability is not a true security risk, it is important that I can get a clean bill of health from the vulnerability scan.

People can create any number of security scans that list a bunch of stuff which aren't actually vulnerabilities - is there some reason this scan in particular is important to you?

@craigdrayton
Copy link
Author

A report from a vulnerability scanner gives me some credibility with potential clients' security teams in lieu of paying for more expensive manual pen testing. Without security approval, my app cannot be adopted by clients. Both of the scanners I've tried have noted this issue.

If this is not a vulnerability, is there an explanation/proof that I can use?
If this is (even a slight, theoretical) vulnerability, is there a workaround/fix?

@stubailo
Copy link
Contributor

stubailo commented Feb 6, 2017

There isn't even a theoretical vulnerability, but I'll leave this issue open in case someone has time to write up some sort of explanation, or if someone discovers a way to set that header in SockJS.

I would be skeptical of scanners like this in general because they catch a lot of false positives and also give you a false sense of security because it's trivial to implement an insecure site that passes all of the tests, but I can understand that it would make clients feel better.

@hwillson
Copy link
Contributor

hwillson commented Feb 6, 2017

Just to add to the discussion - issue #4114 is tracking the upgrade of Meteor's SockJS client. Since PR sockjs/sockjs-node#218 was submitted to SockJS to allow CORS headers to be disabled (and it looks like it's going to be accepted), then this functionality should be available to Meteor at some point in the future.

@craigdrayton
Copy link
Author

Thanks for your responses everyone.

If anyone has time to write a sentence or two, I'd like to be able to add a short statement to my docs on why allowing all CORS requests to SockJS is not a vulnerability. Much appreciated :-)

@mitar
Copy link
Contributor

mitar commented Apr 24, 2017

Personally, I find having DDP endpoints being "public" by default a feature of Meteor. There is nothing wrong by CORS headers allowing anyone to connect t the DDP endpoint because you have to authenticate anyway against DDP to be able to do anything sensitive through DDP. DDP does not use cookies or something like that to authenticate so CSRF or something is not really possible.

So I do not really see why would this be an issue?

@hwillson
Copy link
Contributor

Great point @mitar - I agree, I don't think this is an issue. @craigdrayton - regarding your request for someone to write a sentence or two about why this isn't a vulnerability, @mitar's response in #8317 (comment) should help. Given this (and the fact that Meteor is currently considering a replacement for SockJS in #8621), I think we're safe to close this off. Thanks all!

@mitar
Copy link
Contributor

mitar commented Apr 24, 2017

Also see this comment.

@dobesv
Copy link

dobesv commented Mar 20, 2018

w.r.t. to the security considerations of an open CORS configuration:

Cross-origin requests are blocked by default because:

  1. most websites use cookies to authenticate users
  2. cookies are sent automatically when a browser sends a request to the server that set the cookie, even if the request is triggered by another website
  3. people were able to use this capability to steal data from other websites

A site can protect itself from attacks by cross-origin requests by not using cookies by themselves (or at all) for authentication. Meteor does not use cookies for authentication; instead it stores an authentication token in localStorage when you log in and sends that to the server when it needs to authenticate.

Because meteor's auth system is not vulnerable to typical cross-origin attacks, enabling CORS is not a vulnerability.

@Dsyko
Copy link

Dsyko commented Jun 6, 2018

It seems there may be potential for abuse by leaving an open CORS configuration. I think it would be nice to at least give the option to disable CORS in configuration.

As an example: An attacker could use advertising platforms to cheaply broadcast malicious code that interacts directly with the open websocket service, making it hard to make attributions and to block without locking down the accepted origin.
Attackers could use public lists (leaks) of email addresses in combination with a user enumeration vulnerability. Failed logins using Meteor.loginWithPassword report whether the failure was due to a bad password or because the user does not exist so it is possible to suss out emails with accounts. Using this an attacker could map the application's users in a distributed fashion. Once they know which emails have accounts they could focus a brute force attack on those accounts, again using distributed ad platforms so that attribution is difficult.

A bit far fetched, and unlikely, but there is potential for abuse.

Would Meteor be open to a pull request that allows a flag for disabling CORS on socksjs?

One approach would be to add an ENV flag DISABLE_WEBSOCKET_CORS, following suit on the DISABLE_WEBSOCKETS flag, which when set to true turns on the disable_cors option for socksjs.

@dobesv
Copy link

dobesv commented Jun 9, 2018 via email

@DemisB
Copy link

DemisB commented Dec 5, 2019

Hi!

Sorry to dig that out, but now that sockjs-node is able to receive the disable_cors option, is there a way to enable or pass-in that option by a setting variable of some sort when launching a meteor application?
From what I found, it seems the sockjs server is setup by meteor with a definite set of options, cf. https://github.com/meteor/meteor/blob/master/packages/ddp-server/stream_server.js#L42-L59. It does not seem to be possible to customise those options (apart from modifying that code snippet by hand and restarting the meteor application), do I miss something?

Thank you for your help!

P.S.: I am working with meteor 1.6.1.. I am late, I know 😅

@filipenevola
Copy link
Collaborator

hi @DemisB , yes, this is not possible but you can open a PR implementing this, I would be glad to review. Thanks.

@hems
Copy link

hems commented Apr 14, 2021

any updates on this?

@sonyan
Copy link

sonyan commented Nov 30, 2022

Here is a theoretical vulnerability. DDP is built on top of websocket. since websocket is not secured by CORS policy, an attacker could create a cross-origin WS connection to the server. From there on, the attacker can simply send and subscribe to data from the server.

@mitar
Copy link
Contributor

mitar commented Nov 30, 2022

Why is that a vulnerability and not a feature? It is like having public API endpoints for all Meteor apps. Pretty neat. So one app can pull data from other apps as well. Of course without authentication they should not be able to do much anyway.

@radekmie
Copy link
Collaborator

@sonyan And how can it be used as an attack vector? One can connect to a DDP server from anywhere, not only the browser (e.g., via Node.js script; most languages have decent libraries to work with WebSockets). It's not a problem though, as the authorization is token-based, i.e., one has to send a given message in the socket (attacker would have to know it).

@evolross
Copy link
Contributor

Chiming in that this is still an issue for us. And is reported by security researchers all the time. And sockjs has an option to disable this now.

Just wanted to note this. I'll try to work on a PR for it.

@brianlukoff
Copy link
Contributor

Ran into this too today -- I've created PR #12789 for it based on the discussion in the thread!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests