ruby-openid icon indicating copy to clipboard operation
ruby-openid copied to clipboard

Question concerning CVE-2019-11027

Open rfrohl opened this issue 5 years ago • 35 comments

Hi, I have a question concerning the recent CVE [0]. Could you provide some background which version/commit fixes the issue? Rubygems [1] only shows version 2.7.0. Was version 2.8.0 pulled because of the CVE or was 2.8 just not uploaded by accident ?

Thanks!

[0] https://nvd.nist.gov/vuln/detail/CVE-2019-11027 [1] https://rubygems.org/gems/ruby-openid

rfrohl avatar Jun 11 '19 13:06 rfrohl

We are also facing same issue. Any update on this?

tushar-gandhi avatar Jun 14 '19 10:06 tushar-gandhi

Same here. Has anyone managed to find a workaround to this issue?

jrbyam avatar Jun 19 '19 18:06 jrbyam

Hi @tobiashm, this vulnerability is being flagged by security scanners. Github is also flagging this. Please let us know the plan to fix this or is there any workaround we can apply meanwhile?

ff-cviradiya avatar Jun 20 '19 05:06 ff-cviradiya

The complete list of commits between 2.7.0 and 2.8.0 are available here:

https://github.com/openid/ruby-openid/compare/v2.7.0...v2.8.0

.. yet none look relevant from my quick glance. Anyone else?

lamby avatar Jun 21 '19 19:06 lamby

I've even looked further back in history with no luck. Can someone else have a look too? Perhaps I'm missing something...

lamby avatar Jun 24 '19 08:06 lamby

I had another look but am still a bit stumped... @tobiashm , can you help here? :)

lamby avatar Jun 26 '19 08:06 lamby

The reason v2.8.0 is not on RubyGems is that I haven't been able to contact any of the people who have access to push there :( So if you want to use the latest version, you have to reference it on GitHub.

I will try to look into the security issue soon. Any help is much appreciated :)

tobiashm avatar Jun 26 '19 08:06 tobiashm

Hm, sorry for the confusion but my question here isn't actually about RubyGems but rather I cannot find the relevant commit that fixes this CVE in this Git repository. What am I missing? :)

lamby avatar Jun 26 '19 08:06 lamby

@lamby The part about RubyGems was in reply to the initial post by @rfrohl as clarification.

I have read the linked CVE, but can't really figure out what the vulnerability is supposed to be?

tobiashm avatar Jun 26 '19 08:06 tobiashm

I have read the linked CVE, but can't really figure out what the vulnerability is supposed to be?

Mmm, exactly! To clarify on my end, I thought it was released in 2.8.0 and — as this repo contains a 2.8.0 tag — then the fix would be in here somewhere... :)

lamby avatar Jun 26 '19 08:06 lamby

Does not 2.7 have vulnerability?

marutosi avatar Jun 26 '19 08:06 marutosi

That's my point - I thought 2.7.0 was vulnerable but 2.8.0 contains the fix. Thus the commit fixing the issue would be in the diff between the two, but that does not appear to be the case. So I am missing something fundamental. :)

lamby avatar Jun 26 '19 08:06 lamby

Okay, I understand the confusion.

Short answer: There are currently no version that contains a fix.

Slightly longer: This is due to uncertainty about what the vulnerability actually is! The linked CVE does not contain any concrete information, so I am basically unaware of what would need fixing. I have written to the person who made the report, and will post an update when I know more.

tobiashm avatar Jun 26 '19 11:06 tobiashm

On a side note: The security notification here on GitHub is related to the example Rails app, due to it being based on a very old version of Rails. It has no relation to CVE-2019-11027

tobiashm avatar Jun 26 '19 12:06 tobiashm

I have written to the person who made the report, and will post an update when I know more.

Anything more? :)

lamby avatar Jul 01 '19 18:07 lamby

Looking back at everything here, I'm still somewhat confused and not sure how to help out here. :) Anybody or anything I should contact on this?

lamby avatar Jul 05 '19 18:07 lamby

@lamby Does https://github.com/openid/ruby-openid/pull/121 address CVE-2019-11027 ? I saw mention of SSRF and behaviour similar to that in the marc.info mailing list posts for the CVE. It isn't part of 2.8.0 - which could be why you didn't see a fix in the 2.7.0 to 2.8.0 diff.

bwalding avatar Jul 16 '19 03:07 bwalding

Ah, possibly. Also perhaps I just thought this was a "meaningless" ordering change, but... :)

lamby avatar Jul 16 '19 14:07 lamby

Is there an ETA on when a fixed version will be released and pushed to rubygems.org?

papaphil avatar Jul 25 '19 16:07 papaphil

If you were looking for 2.8 to come to rubygems, I found this on gitlab

papaphil avatar Jul 25 '19 16:07 papaphil

By looking at the code changes on gitlab, I do not think there is any fix made for this issue. https://gitlab.com/gitlab-org/security-products/gemnasium-db/commit/4c496a196b7626ee15583035f156755cd0d24aa7

tushar-gandhi avatar Jul 26 '19 06:07 tushar-gandhi

@tobiashm I am guessing you mean you have contacted the person referenced - if so have you been able to work anything out?

brianmay avatar Aug 11 '19 22:08 brianmay

Colleagues, regarding https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11027, I will ask the Mitre team to share the detailed information originally provided to them on the CVE listing. The MITRE CVE team kept the details to a minimum when first published. Per the advice of the OpenID leadership team, I had originally tried reaching out to ruby-openid project maintainers. That communication was unsuccessful, so I have spent the last several months working directly with ~50 known affected app developers instead (that I had detected ... there are likely many more).

The vulnerability affects OpenID 2.0 implementations only, and lies in the Yadis consumer discovery functionality provided by the gem. The vulnerability can be remotely exploited to perform a Server Side Request Forgery (SSRF) attack. At a minimum, affected web services will be vulnerable to Blind SSRF. Depending on implementation, some web service will be vulnerable to full SSRF. Full SSRF can be trivially exploited to fingerprint/map network services (local, private, public), but in the worst case scenario; either can lead to host/cloud service compromise and/or loss of customer data depending on app deployment architecture. I did come across one vulnerable web app where Blind SSRF could be used to perform an authentication bypass against a victim (user), by spoofing an OpenID Provider (OP).

Application developers still using/supporting OpenID 2.0 that chose to not implement consumer discovery are not affected. If consumer discovery is required, or application developers do not have the capability to modify/customize the deployment of ruby-openid can mitigate the risk by performing strict checks (whitelisting) against the "claimed_id" URL supplied to the application in an OpenID 2.0 assertion request. The weakness is also mitigated if developers chose to implement signature verification of the OpenID 2.0 assertion request PRIOR to performing the consumer discovery step. As stated in the CVE listing, developers who based their OpenID integration heavily on the "example app" provided by ruby-openid are at highest risk.

App developers can test their applications for vulnerability by sending a fake OpenID 2.0 assertion request to the appropriate endpoint(s) which handle OpenID 2.0 assertion requests. Substitute a malicious URL in the claimed_id URL parameter, ensuring you have access to the web logs for that specific web service. App developers could also substitute 127.0.0.1 or 0.0.0.0 for the hostname in the URL (or various alternatives) and monitor their own web logs. Look for HTTP requests in the web logs showing a User-Agent of "ruby-openid/2.X.Y" (i.e. ruby-openid/2.7.0)

Look to line 77 of https://github.com/openid/ruby-openid/blob/master/lib/openid/yadis/discovery.rb#L77 which is where an HTTP request is made to the specified "discovery URL". This traces back to the Yadis.discover() function in https://github.com/openid/ruby-openid/blob/master/lib/openid/consumer/discovery.rb#L47 at line 407, and to the Yadis.get_service_endpoints() function in https://github.com/openid/ruby-openid/blob/master/lib/openid/yadis/services.rb#L16 at line 16.

IMO, the source of the weakness can be traced back to the Final OpenID 2.0 spec (https://openid.net/specs/openid-authentication-2_0.html#anchor12). As "7.3 Discovery" comes before "11. Verifying Assertions", a forged assertion request manipulating the value of the claimed_id URL parameter can be exploited with SSRF attacks, and can even potentially lead to authentication bypass condition should the vulnerable web application then submit a second HTTP request to the URL specified in a spoofed OpenID Provider (OP) XRDS response, and blindly trust the value of the "is_valid" field (in the 2nd HTTP response body). This was observed only once during testing, but is worth noting due to the critical impact.

A web application that is vulnerable to full SSRF (instead of just Blind SSRF) will return ruby-openid's detailed error message back to the user of the application, which could look something like this if a tester used a URL of "http:%2f%2f127.0.0.1:22%2f" for the claimed_id URL parameter: "Login failed: Verification of unknown failed: Failed to fetch identity URL http://127.0.0.1:22/ : Error fetching http://127.0.0.1:22/: wrong status line: "SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.6""

Line 79 of https://github.com/openid/ruby-openid/blob/master/lib/openid/yadis/discovery.rb#L79 is used to handle an exception when an HTTP request made to a specified "discovery URL" results in some form of connection error. This generates an error that concatenates the string "Failed to fetch identity URL " with the URL supplied to the 3P app in the claimed_id URL parameter, with another string " : " followed finally by the error message returned by Ruby's http library, which looks like this: "Error fetching http://127.0.0.1:22/: wrong status line: YYYYYYYYYY".

The example app's https://github.com/openid/ruby-openid/blob/master/examples/rails_openid/app/controllers/consumer_controller.rb#L67 is where the error message that looks like:"Verification of unknown failed : " + error returned by https://github.com/openid/ruby-openid/blob/master/lib/openid/yadis/discovery.rb#L79

For this reason, it is highly recommended that ruby-openid be updated so that this behavior of returning details of connection errors is non-default (return a generic error message instead), and a warning added (in comments) for developers considering to over-ride the safe default.

In summary:

  • This specific vulnerability affects OpenID 2.0 implementations only
  • This specific vulnerability was not fixed by 2.8
  • Remediation may be difficult! One solution might be to disable Yadis discovery in ruby-openid by default, with warnings clearly identified in comments explaining the risks (of enabling it), and how to potentially mitigate them. I do not claim to know the correct answer
  • Regardless of the path chosen (to remediate), I recommend that detailed error messages related to communication errors be replaced by generic errors. This does not prevent Blind SSRF, but mitigates Full SSRF
  • For application developers, mitigations for affected apps exist: ** Disable Yadis discovery if not needed ** If Yadis discovery is required, or cannot be disabled, add your own strict checks against the value of the claimed_id URL parameter at the very beginning of OpenID 2.0 assertion processing ** Do not attempt to mitigate the SSRF risk by using "blacklisting" -- a determined attacker will find a way!

Sorry it took a while to divulge details, I was trying to protect known vulnerable apps, and wasn't getting any response back from project maintainers...

Best Regards

setenforce1 avatar Aug 12 '19 05:08 setenforce1

@setenforce1 If this is a problem with the Final OpenID 2.0 spec, I wonder if other implementations might be vulnerable also, e.g. https://github.com/openid/python-openid/ ?

brianmay avatar Aug 12 '19 07:08 brianmay

@setenforce1 If I understand this correctly, the problem is that we are using the data from the assertions before we have verified the assertions? So the discovery could be using forged values, and as such we could be trying to connect to a URL that the attacker wants us to connect to?

If so, why not just do the verification first before the discovery? Is there some problem here that I have missed?

brianmay avatar Aug 12 '19 07:08 brianmay

@brianmay, any OpenID 2.0 implementation that supports consumer discovery by default, and doesn't do so safely is potentially at risk. During testing I did stumble upon another vulnerable implementation called LightOpenID, and filed https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11066. Same issue, had to work directly with known affected app developers, as this library is not actively maintained.

Keep in mind that OpenID Connect was created to address the weaknesses inherent in OpenID 2.0, so where possible/feasible, project and ecosystem maintainers should strive to deprecate support for OpenID 1.0 and 2.0. That being said, OpenID Connect is no panacea either, researchers have found plenty of weaknesses that app developers should be aware of (search Google), to include SSRF and OP spoofing.

setenforce1 avatar Aug 12 '19 18:08 setenforce1

There's a release v2.9.0 which includes changes to some of issues discussed here.

But it also seems that part of it has to do with how people choose to use the library, or am I mistaking?

The demo app is not meant as a scaffold, but more of an exploration tool. That's probably why the full internal error messages are displayed in flash. That's certainly not something that anyone should do in a production app. I've started looking into rewriting the demo app in a newer Rails version, as it's currently based on a very old version, which is also causing security warnings here on Github. Unfortunately I don't really have much time to devote to this :(

tobiashm avatar Sep 17 '19 20:09 tobiashm

@papaphil

Is there an ETA on when a fixed version will be released and pushed to rubygems.org?

I currently don't have write access to the gem at rubygems.org, and have tried to contact some of the owners, but so far none have replied. So for now you'll have to reference the code here on github.

tobiashm avatar Sep 17 '19 20:09 tobiashm

Hey @tobiashm,
We maintain this gem in Debian as a separate package.
Whilst trying to fix the CVE, we'd need a patch; is there any way to get a single patch which is actually fixing the CVE?

utkarsh2102 avatar Oct 07 '19 16:10 utkarsh2102

@utkarsh2102 I'm not entirely sure what the CVE issue is exactly, so I cannot say if it has been fixed in the latest release. There are a couple of Yardis discovery related pull-requests that have been merged since 2.8.0.

Also, I have gained access to rubygems.org so the latest release is now available there 🎉

tobiashm avatar Oct 08 '19 19:10 tobiashm