XSS

Bug #1463698 reported by Amit
28
This bug affects 3 people
Affects Status Importance Assigned to Milestone
OpenStack Dashboard (Horizon)
Invalid
Critical
Unassigned
OpenStack Object Storage (swift)
Invalid
Undecided
Unassigned
OpenStack Security Advisory
Won't Fix
Undecided
Unassigned

Bug Description

2.14.2

Revision history for this message
Christian Schwede (cschwede) wrote :

Do you have more details on this? "2.14.2" as bug description doesn't help that much, it's not even a version tag in Swift.

Did you notice a XSS vulnerability in Swift and if so, where?

Revision history for this message
Amit (amitghadigaonkar0) wrote :

I've accessed Swift through Horizon Dashboard..[2.14.2]

Steps to Reproduce : 1. Login to Horizon Portal.
2.Create a Container through Object Store.
3.Make the Container as Public.
4.Now Upload a image file having XSS payload.[XSS payload into image metadata]
5.Browse the Public URL of the Container and access the uploaded file.

Revision history for this message
Christian Schwede (cschwede) wrote :

I think I'm a little bit lost - accessing an object in a *public* container is not a security issues, is it?

Preventing users from storing malicious content in an object is close to impossible.

So I don't think this is an issue in Swift or Horizon. Am I wrong?

Revision history for this message
Amit (amitghadigaonkar0) wrote :

As this bug can exploited on websites when header data is displayed as-is on the page. It clearly shows how there’s many hidden user controlled inputs that can be exploited by malicious users. This is why it’s important to always follow the golden rule “Filter input, Escape output”

I believe that it is important to run filter engines on EXIF metadata just as if it is a normal web attack or a script injection vector.

use the security header for prevention of xss
X-XSS-Protection: 1; mode=block

And mark cookie as HTTPOnly and Secure

Revision history for this message
Amit (amitghadigaonkar0) wrote :
Revision history for this message
Christian Schwede (cschwede) wrote :

> This is why it’s important to always follow the golden rule “Filter input, Escape output”

Fully agree - but I think it's the task of the application that stores data inside Swift. Swift itself is primarily a storage system, and it should not alter blob data by default.

> use the security header for prevention of xss X-XSS-Protection: 1; mode=block

So I looked this up and it seems that this is by default enabled in recent browser, and this header only re-enables it in case a user disabled this on purpose (https://www.owasp.org/index.php/List_of_useful_HTTP_headers; IIRC Firefox uses this also by default).
Adding this header might still be a useful choice in some usecases; so maybe this could be added as a (per-container) configurable option/metadata entry? But in that case it's more an enhancement IMO.

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
Jeremy Stanley (fungi) wrote :

I agree with Christian's position on this. I don't think either Horizon or Swift should be limiting the content that the owner of the account can upload into a container by default (though having an optional feature to filter either when storing or serving seems reasonable). Pretty sure this falls somewhere between classes D and E in our report taxonomy, and so we wouldn't publish a security advisory for this nor recommend it for backporting to existing stable release versions. https://security.openstack.org/vmt-process.html#incident-report-taxonomy

Revision history for this message
John Dickinson (notmyname) wrote :

I too agree with Christian's view. It's not a bug that you can store Bad Things (tm) in Swift. Unless there is more clarity about a vulnerability or exploit, I would like to close this bug report as invalid.

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

If no one objects, we'll open this bug by the end of the week.

Revision history for this message
Amit (amitghadigaonkar0) wrote :

Clarity to the Reported Issue attached below..

Revision history for this message
John Dickinson (notmyname) wrote :

Is that csrftoken a value that is being used by Horizon?

Is your Swift deployment at the same domain as Horizon? That would be bad. You should never have protected content (eg the parts of an app behind auth) at the same domain as where untrusted users can upload content. Doing so allows untrusted users to load data in the same context as the protected content, thus allowing javascript (or whatever) to get/set cookies etc. If untrusted users are storing content in Swift, you should always have Swift on its own domain.

Is that the issue you're seeing here? What's the difference between serving these bad-EXIF pictures through Swift or through some other web server?

Revision history for this message
Christian Schwede (cschwede) wrote :

csrftoken is used in Horizon; it's a a token from Django and thus used in other Django applications as well.

John, I think your note about using the same domain is worth a documentation update. But that is more like an improvement; IMO this reported bug is not directly related to Swift.

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

On a typical openstack deployment, swift is accessible on the same domain as Horizon, but on a different port (8080).

While this let the csrftoken to leak, it can't be reused on horizon because django's Same Origin Policy will prevent request coming from port 8080.

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

If no one objects, we'll open this bug by the end of the week.

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

Adding ossg-coresec to discuss an eventual OSSN or security-guide update.

Changed in ossa:
status: Incomplete → Won't Fix
information type: Private Security → Public
Jeremy Stanley (fungi)
description: updated
Revision history for this message
Robert Clark (robert-clark) wrote :

Does Horizon filter metadata appropriately when it renders object information? I'm concerned that this could be a security issue for typical deployments (the combination of Horizon and Swift).

Revision history for this message
Matthias Runge (mrunge) wrote :

Horizon filters metadata by default. There still might be occurances, where filtering is not effective, i.e. when not using djangos template engine or filtering is explicitly switched off.

csrftoken is revealed at each form, but it's valid only once, and has to fit to the form location.

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

From the attached screenshots (specifically screenshot 4) it looks like script is being run. Is this happening automatically when retrieving from the Swift object server?

If Horizon is failing to filter metadata for some fields it's worth tracking down and fixing those.

Revision history for this message
Matthias Runge (mrunge) wrote :

where do you see screenshot 4? Which one is it?

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

@mrunge in message #11 Amit uploaded a .zip file containing four screenshot images. I'm referring to "XSS4.jpg" in that archive.

Revision history for this message
Samuel Merritt (torgomatic) wrote :

Sounds like escaping of content needs to happen where the content is embedded. Swift just gives you back what you gave it.

Adding Horizon, marking invalid for Swift.

Changed in swift:
status: Incomplete → Invalid
Revision history for this message
Matthias Runge (mrunge) wrote :

Since this contains a public security vulnerability, I'm bumping this to next snapshot, increasing priority to get attention.

Changed in horizon:
milestone: none → liberty-rc1
importance: Undecided → Critical
Revision history for this message
Masco (masco) wrote :

@amit, could you please share the EXJF1.jpeg
it will be very helpful to reproduce/investigate the bug.

thanks in advance.

Revision history for this message
Amit (amitghadigaonkar0) wrote :

I've just edited the Model Name of a CAM pic from NIKON D80 to a script tag and uploaded it...

Revision history for this message
Masco (masco) wrote :

I am not able to reproduce the bug with the below steps,

1. added the script " <script>alert(2)</script>" in image metadata(model field)
2. created a public container
3. uploaded the file in container
4. try to download the file using the public url.
5. file is downloaded successfully.

Please correct me if i am doing anything wrong in my steps.

PFA the file with XSS payload.

Revision history for this message
Amit (amitghadigaonkar0) wrote :

How I did was using a pic from my DSLR that already had Camera Model Name and other fields in it.
Edit the Model Name field using Exiftool from Linux and add script tag to the field as shown below in my case...

Camera Model Name: NIKON D80 <script>alert(document.cookie)</script>

Revision history for this message
Lin Hua Cheng (lin-hua-cheng) wrote :

Amit failed to respond to an important question, if horizon and swift is running on the same domain.

From the screenshot, the image is opened using the Swift Public URL endpoint.

And it seems like Swift is running on the same domain as horizon, allowing the script to access the horizon cookie.

The reported bug is invalid for Horizon.

This is more of a deployment issue.

Horizon already documented configuration how to avoid XSS attack in: https://github.com/openstack/horizon/blob/master/doc/source/topics/deployment.rst

By setting:
CSRF_COOKIE_HTTPONLY = True
SESSION_COOKIE_HTTPONLY = True

Changed in horizon:
status: New → Invalid
Revision history for this message
Lin Hua Cheng (lin-hua-cheng) wrote :

Amit, please correct me if my understanding of your deployment is wrong.

Changed in horizon:
milestone: liberty-rc1 → none
Revision history for this message
Travis McPeak (travis-mcpeak) wrote :

Sorry I'm confused - it still looks like we're failing to sanitize input which allows script to run as part of the rendering of a metadata field.

Regardless of whether it can get the cookie or not, this seems like a pretty big security issue to me. There are plenty of other security problems associated with allowing malicious scripts to run.

Am I missing something?

Revision history for this message
Lin Hua Cheng (lin-hua-cheng) wrote :

From the earlier thread, Jeremy and John mentioned that we should not be altering content that the user uploads to their containers.

The rendering of the metadata field I believe is performed by the browser not by Swift or Horizon.

Revision history for this message
Masco (masco) wrote :

I have tested in firefox and chrome browser, it is working fine.
from the attached snapshot, we can make-out, amit is tested in IE.

if someone test in IE, we can confirm that the issue is in IE.

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

Duplicates of this bug

Other bug subscribers

Remote bug watches

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