Generate and download keypair GET endpoint allows CSRF attacks

Bug #1575913 reported by Steve McLellan
12
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Dashboard (Horizon)
Fix Released
High
Gary W. Smith
OpenStack Security Advisory
Won't Fix
Undecided
Unassigned

Bug Description

Requests to create (and download) nova keypairs are made as GETs. As such the CSRF token is not sent nor validated on these requests. This breaks the principle Django's CSRF middleware relies upon which is that requests with side effects should not cause side effects. I'm told there was a reason for doing this related to being able to send the data back to the browser, and that this may not be trivial to fix.

Filing this as a security bug since a malicious site could fool a user into creating keypairs. The attacker would not gain access to the contents, so the impact is not as serious as it might seem at first glance.

See https://github.com/openstack/horizon/blob/master/openstack_dashboard/dashboards/project/access_and_security/keypairs/views.py#L112

Tags: security
Revision history for this message
Jeremy Stanley (fungi) wrote :

Since this report concerns a possible security risk, an incomplete security advisory task has been added while the core security reviewers for the affected project or projects confirm the bug and discuss the scope of any vulnerability along with potential solutions.

Changed in ossa:
status: New → Incomplete
description: updated
Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

@horizon-coresec, please triage this bug report.

I wasn't able to reproduce this issue and keypair creation went through a POST request. Any chance you provide steps to reproduce ?
Or perhaps it's the regeneration of existing keypair that is possible...

Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

@horizon-coresec: any progress ?

Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

@horizon-coresec: any chance you had a look at this bug ?

Revision history for this message
Rob Cresswell (robcresswell-deactivatedaccount) wrote :

I've been looking into this today. The GET seems to be when the action is initialised (as in, the modal is launched), but the actual request appears to be a POST as far as I can tell. The modal itself is a form with POST and submit set as expected... Steve, could you check again?

Revision history for this message
Steve McLellan (sjmc7) wrote :

The code in https://github.com/openstack/horizon/blob/master/openstack_dashboard/dashboards/project/access_and_security/keypairs/views.py#L114 looks like it's a GET and that's where the keypair is generated and returned. There's a link generated to it in https://github.com/openstack/horizon/blob/master/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html

This was a long time ago now but the explanation i was given at the time was (I think) that a POST created problems returning a file for download.

PM me if this still doesn't make sense; it was a while ago and i could be off-base.

Revision history for this message
Rob Cresswell (robcresswell-deactivatedaccount) wrote :

I just had this demonstrated, it was a misinterpretation on my part. You can hit this very easily, its a valid bug and needs patching. Steve, do you have a patch?

Revision history for this message
Rob Cresswell (robcresswell-deactivatedaccount) wrote :

FYI, to recreate, create a file with this content:

<html><body>
  <img src="http://localhost:8000/project/access_and_security/keypairs/hole1/regenerate/generate/">
  <img src="http://localhost:8000/project/access_and_security/keypairs/hacked/generate/">
  <img src="http://localhost:8000/api/nova/keypairs/hacked2/">
</body></html>

Then log in to the Horizon, and open that file in a new tab. Then check your keypairs :) I believe thats a valid application of this issue.

Revision history for this message
Steve McLellan (sjmc7) wrote :

No, I don't, sorry :( I'd hope it would be as simple as changing the request method and altering the download page to use POST but at the time I was told that it was implemented as a GET because of difficulties doing it properly; I can't recall the details now.

Revision history for this message
Jeremy Stanley (fungi) wrote :

Just to restate, for clarity: This is a CSRF bug in Horizon allowing a malicious site to coerce a victim into creating Nova keypairs, but does not get the attacker access to those keypairs nor allow them to cause the victim to perform any other actions (using the generated keypairs or otherwise). Without an actual exploit scenario leveraging this, I find it hard to justify an embargo (much less advisory) so am subscribing the ossg-coresec team for their input on switching the report to public.

Revision history for this message
Travis McPeak (travis-mcpeak) wrote :

I agree with Jeremy. Worst case impact based on description seems like creating a lot of key-pairs and annoying the user.

That being said, it's valid CSRF and should be fixed, albeit in the open.

Revision history for this message
Steve McLellan (sjmc7) wrote :

I'm fine treating this as open; it was filed as a security bug out of caution but as it seems there's no actual exploitable security hole (i.e. it's just an opportunity to annoy a user) it seems reasonable to open it up.

Revision history for this message
Jeremy Stanley (fungi) wrote :

Thanks, Travis!

I propose that this be considered a class D report: "Not a vulnerability, just a bug with (some) security implications, e.g., strengthening opportunities."

https://security.openstack.org/vmt-process.html#incident-report-taxonomy

If there are no objections, I'll switch the bug to public early next week and mark it as a security hardening opportunity.

Jeremy Stanley (fungi)
description: updated
Changed in ossa:
status: Incomplete → Won't Fix
information type: Private Security → Public
tags: added: security
Revision history for this message
Robert Clark (robert-clark) wrote : Re: [Bug 1575913] Re: Generate and download keypair GET endpoint allows CSRF attacks
Download full text (3.4 KiB)

Im put of the office so attempting to reply by email on phone.

A concern is that in the attack described, new keypairs could be created
that would later used in a social engineering attack. Naming keys certain
ways might encourage their use in future or as part of a more complex
attack scenario.

On 28 Nov 2016 17:15, "Jeremy Stanley" <email address hidden> wrote:

> ** Description changed:
>
> - This issue is being treated as a potential security risk under embargo.
> - Please do not make any public mention of embargoed (private) security
> - vulnerabilities before their coordinated publication by the OpenStack
> - Vulnerability Management Team in the form of an official OpenStack
> - Security Advisory. This includes discussion of the bug or associated
> - fixes in public forums such as mailing lists, code review systems and
> - bug trackers. Please also avoid private disclosure to other individuals
> - not already approved for access to this information, and provide this
> - same reminder to those who are made aware of the issue prior to
> - publication. All discussion should remain confined to this private bug
> - report, and any proposed fixes should be added to the bug as
> - attachments.
> -
> Requests to create (and download) nova keypairs are made as GETs. As
> such the CSRF token is not sent nor validated on these requests. This
> breaks the principle Django's CSRF middleware relies upon which is that
> requests with side effects should not cause side effects. I'm told there
> was a reason for doing this related to being able to send the data back
> to the browser, and that this may not be trivial to fix.
>
> Filing this as a security bug since a malicious site could fool a user
> into creating keypairs. The attacker would not gain access to the
> contents, so the impact is not as serious as it might seem at first
> glance.
>
> See
> https://github.com/openstack/horizon/blob/master/openstack_
> dashboard/dashboards/project/access_and_security/keypairs/views.py#L112
>
> ** Changed in: ossa
> Status: Incomplete => Won't Fix
>
> ** Information type changed from Private Security to Public
>
> ** Tags added: security
>
> --
> You received this bug notification because you are a member of OSSG
> CoreSec, which is subscribed to the bug report.
> https://bugs.launchpad.net/bugs/1575913
>
> Title:
> Generate and download keypair GET endpoint allows CSRF attacks
>
> Status in OpenStack Dashboard (Horizon):
> New
> Status in OpenStack Security Advisory:
> Won't Fix
>
> Bug description:
> Requests to create (and download) nova keypairs are made as GETs. As
> such the CSRF token is not sent nor validated on these requests. This
> breaks the principle Django's CSRF middleware relies upon which is
> that requests with side effects should not cause side effects. I'm
> told there was a reason for doing this related to being able to send
> the data back to the browser, and that this may not be trivial to fix.
>
> Filing this as a security bug since a malicious site could fool a user
> into creating keypairs. The attacker would not gain access to the
> contents, so the impact is not as serious as it ...

Read more...

Revision history for this message
Jeremy Stanley (fungi) wrote :

Agreed, this is certainly worth fixing, and maybe even worth backporting. I'm just questioning whether its severity is sufficient to warrant wider communication given that exploiting it would rely on social engineering or some other vulnerability allowing you to obtain a user's keys or compel them to take some action through the UI/API (in which case there are probably far easier ways to achieve the desired outcome from your victim anyway). The line between a hardening opportunity (D) and an impractical vulnerability (C1) is often pretty fuzzy.

Revision history for this message
Travis McPeak (travis-mcpeak) wrote :
Download full text (5.0 KiB)

But still, the attacker wouldn't be able to access the key. So the
attacker could possible trick the victim to add a key they didn't mean to,
but the attacker doesn't have the corresponding key if I understand
correctly.

> On Nov 29, 2016, at 6:54 AM, Robert Clark <email address hidden>
wrote:
>
> Im put of the office so attempting to reply by email on phone.
>
> A concern is that in the attack described, new keypairs could be created
> that would later used in a social engineering attack. Naming keys certain
> ways might encourage their use in future or as part of a more complex
> attack scenario.
>
>> On 28 Nov 2016 17:15, "Jeremy Stanley" <email address hidden> wrote:
>>
>> ** Description changed:
>>
>> - This issue is being treated as a potential security risk under
embargo.
>> - Please do not make any public mention of embargoed (private) security
>> - vulnerabilities before their coordinated publication by the OpenStack
>> - Vulnerability Management Team in the form of an official OpenStack
>> - Security Advisory. This includes discussion of the bug or associated
>> - fixes in public forums such as mailing lists, code review systems and
>> - bug trackers. Please also avoid private disclosure to other
individuals
>> - not already approved for access to this information, and provide this
>> - same reminder to those who are made aware of the issue prior to
>> - publication. All discussion should remain confined to this private bug
>> - report, and any proposed fixes should be added to the bug as
>> - attachments.
>> -
>> Requests to create (and download) nova keypairs are made as GETs. As
>> such the CSRF token is not sent nor validated on these requests. This
>> breaks the principle Django's CSRF middleware relies upon which is that
>> requests with side effects should not cause side effects. I'm told
there
>> was a reason for doing this related to being able to send the data back
>> to the browser, and that this may not be trivial to fix.
>>
>> Filing this as a security bug since a malicious site could fool a user
>> into creating keypairs. The attacker would not gain access to the
>> contents, so the impact is not as serious as it might seem at first
>> glance.
>>
>> See
>> https://github.com/openstack/horizon/blob/master/openstack_
>> dashboard/dashboards/project/access_and_security/keypairs/views.py#L112
>>
>> ** Changed in: ossa
>> Status: Incomplete => Won't Fix
>>
>> ** Information type changed from Private Security to Public
>>
>> ** Tags added: security
>>
>> --
>> You received this bug notification because you are a member of OSSG
>> CoreSec, which is subscribed to the bug report.
>> https://bugs.launchpad.net/bugs/1575913
>>
>> Title:
>> Generate and download keypair GET endpoint allows CSRF attacks
>>
>> Status in OpenStack Dashboard (Horizon):
>> New
>> Status in OpenStack Security Advisory:
>> Won't Fix
>>
>> Bug description:
>> Requests to create (and download) nova keypairs are made as GETs. As
>> such the CSRF token is not sent nor validated on these requests. This
>> breaks the principle Django's CSRF middleware relies upon which is
>> that requests with side effects should not cause side ...

Read more...

Changed in horizon:
assignee: nobody → Gary W. Smith (gary-w-smith)
status: New → In Progress
Changed in horizon:
milestone: none → pike-3
importance: Undecided → High
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to horizon (master)

Reviewed: https://review.openstack.org/367629
Committed: https://git.openstack.org/cgit/openstack/horizon/commit/?id=d07fedc45f91449787d939a5bf4cc00a0d100652
Submitter: Jenkins
Branch: master

commit d07fedc45f91449787d939a5bf4cc00a0d100652
Author: Matt Borland <email address hidden>
Date: Thu Sep 8 14:50:23 2016 -0600

    Use POST not GET for keypair generation

    This patch fixes the Cross-Site Request Forgery (CSRF) attack against
    the keypair generation pages:
    - HORIZON_URL/project/key_pairs/PAIRNAME/generate/
    - HORIZON_URL/project/key_pairs/PAIRNAME/download/
    These pages exposed creating and/or overwriting a keypair with a given
    name via a CSRF attack.

    This patch closes these holes by using only POST-based keypair creation,
    and exposing the keypair in the contents of a modal dialog instead of a
    download, which ultimately requires a GET. It uses the same client-side
    features for both the Launch Instance keypair creation and Compute / Key
    Pairs panel.

    Closes-Bug: 1575913
    Change-Id: Ie5ca28ff2bd806eb1481eba6f419b797b68856b6

Changed in horizon:
status: In Progress → Fix Released
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix included in openstack/horizon 12.0.0.0b3

This issue was fixed in the openstack/horizon 12.0.0.0b3 development milestone.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.