Horizon exposes secrets via volume transfer URL

Bug #2048493 reported by Andrew Ruthven
260
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Dashboard (Horizon)
Fix Released
Critical
Radomir Dopieralski
OpenStack Security Advisory
Incomplete
Undecided
Unassigned

Bug Description

Hey folks,

During our latest annual penetration test of our OpenStack based cloud, it was discovered that Horizon, when creating a volume transfer to another project, provides a link to download the transfer credentials to a file which can then be saved. This link includes the transfer secret aka authorisation key, and is sent as a GET to the server. The server code parses the URL, pulls out the UUID and authorisation key and the renders a template to be returned. The use of GET here exposes the authorisation key.

As you're no doubt aware, sensitive information contained within URLs can be recorded in multiple locations, including the user’s web browser, the web server, and any forward or reverse proxy servers situated between the two endpoints. In addition, URLs are commonly displayed on-screen, bookmarked, or shared via email by users. When users follow off-site links, these URLs may also be revealed to third parties through the Referrer header. Therefore, inserting credentials into a URL heightens the vulnerability of them being intercepted and subsequently exploited by potential attackers (in this case the Referrer header is unlikely).

To reproduce:

1. Configure a browser to use an intercepting proxy such as Burp.
2. Log in to Horizon as a user with privileges to manager volumes.
3. Navigate to: ”Volumes” > ”Volumes”.
4. Choose a volume then select the ”Create Transfer” action.
5. Provide a transfer name then click the ”Create Volume Transfer” button.
6. Observe that the ”Transfer ID” and ”Authorisation Key” are populated.
7. Click the ”Download transfer credentials” button to download the credentials.
8. Observe a URL like the following in Burp:
    GET / project / volumes /98fd<<redacted >>66b0/ download_creds /363e<< redacted >>27c1 HTTP /1.1
    Host: dashboard.example.com

This is made worse by the fact that Cinder doesn't expire transfer requests:
    https://opendev.org/openstack/cinder/src/commit/4ee1bdaf648064adb6ad9f0e4fda6adc6ad1cbb6/cinder/transfer/api.py#L164

Path match in Horizon:
    https://opendev.org/openstack/horizon/src/commit/fb1a3e88daf479b8fc5edcf26995fb860c76d05c/openstack_dashboard/dashboards/project/volumes/urls.py#L66 (and is present in master)

Code in Horizon which generates the result:
    https://opendev.org/openstack/horizon/src/commit/fb1a3e88daf479b8fc5edcf26995fb860c76d05c/openstack_dashboard/dashboards/project/volumes/views.py#L672 (and is present in master)

Ideally the generation of creds file would be fully in the browser, there is no need for a round trip to the server. If a round trip is necessary, then it should be via a POST and not include the transfer key in the URL.

Kind regards,
Andrew

Revision history for this message
Andrew Ruthven (andrew-etc) wrote :

This would have been introduced when fixing: https://bugs.launchpad.net/horizon/+bug/1515648

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.

description: updated
Changed in ossa:
status: New → Incomplete
Revision history for this message
Andrew Ruthven (andrew-etc) wrote :

Hey, it has been two weeks since I reported this issue. Just wondering if there are any updates.

Changed in horizon:
status: New → Confirmed
Changed in horizon:
importance: Undecided → Critical
Revision history for this message
Andrew Ruthven (andrew-etc) wrote :

Hey folks, I'm aware that the end of the embargo period - 2024-04-07 - is quickly approaching. Is there any progress on resolving this before this ticket is made public?

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

Unfortunately it's looking like the Horizon developers haven't found time to address this. I do wish project teams could better predict whether they're likely to prioritize work on a reported vulnerability and say sooner if they can't, so that we could switch them to public straight away and see if that urges anyone else in the community to work on a fix instead.

I'll try to poke them again and see if I can get a response. If any Horizon developer does see this, please comment to let us know whether we should keep it private for two more weeks or switch it to public now. Thanks!

Changed in horizon:
assignee: nobody → Radomir Dopieralski (deshipu)
Revision history for this message
Radomir Dopieralski (deshipu) wrote :

This patch makes it pass the auth_key through the session instead of the URL. That should solve the immediate problem.

I might have a better patch soon that doesn't use the session.

Revision history for this message
Radomir Dopieralski (deshipu) wrote :

A better approach, that avoids using the session and passes the auth_key in the POST data.

Changed in horizon:
status: Confirmed → In Progress
Revision history for this message
Jeremy Stanley (fungi) wrote :

What release was the bug introduced in? Has it been this way since at least Zed, or did it only show up in a later release? Just trying to figure out what backports we'll need and what affected versions to list if we issue an advisory for this.

Can another Horizon reviewer give the proposed patch in comment #7 a once-over?

Since the possible exploit scenarios for this are somewhat limited by client-side security measures and safe browsing practices, I think we can proceed in public and try to get this backported to stable/2024.1 in time for the upcoming release. Does anyone have concerns with taking that approach for expediency?

Revision history for this message
Radomir Dopieralski (deshipu) wrote :

The bug was present from the very beginning when that functionality was implemented 12 years ago: https://opendev.org/openstack/horizon/commit/46ad19dbf08b9e313c257fa3f0ad07ec1e93ccb1

I have no concerns with making this issue public.

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

Thanks! For the sake of expediency, and because of the limited scope of risk this represents, let's proceed to fix this in public. I'm switching the bug to Public Security, so feel free to push the patch to Gerrit for ease of review.

description: updated
information type: Private Security → Public Security
Revision history for this message
Radomir Dopieralski (deshipu) wrote :
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to horizon (master)

Fix proposed to branch: master
Review: https://review.opendev.org/c/openstack/horizon/+/914104

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to horizon (master)

Reviewed: https://review.opendev.org/c/openstack/horizon/+/914104
Committed: https://opendev.org/openstack/horizon/commit/ccef197e038a2cd3aa36fd0961686163c8524306
Submitter: "Zuul (22348)"
Branch: master

commit ccef197e038a2cd3aa36fd0961686163c8524306
Author: Radomir Dopieralski <email address hidden>
Date: Mon Mar 25 12:10:11 2024 +0100

    Don't pass the auth_key for volume transfer in the URL

    Instead we pass it as data in the POST request.

    Closes-Bug: #2048493

    Change-Id: I9085eb146b8f013909f6369b731c076aba3216ab

Changed in horizon:
status: In Progress → Fix Released
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

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