Cross-Frame Scripting (XFS) Clickjacking vulnerability with legacy browsers

Bug #1461154 reported by Brian Tully
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Dashboard (Horizon)
Fix Released
Low
Brian Tully
OpenStack Security Advisory
Won't Fix
Undecided
Unassigned

Bug Description

Vulnerability Details

A Cross-Frame Scripting (XFS) vulnerability can allow an attacker to load the vulnerable application inside an HTML iframe tag
on a malicious page.

Impact

An attacker could use XFS to devise a Clickjacking attack to conduct phishing, frame sniffing,
social engineering or Cross-Site Request Forgery attacks.

Recommendations

Set the HTTP X-Frame-Options header to one of the following:
DENY - deny any frames
SAMEORIGIN - frames are only allowed from the same origin
ALLOW-FROM - a list of allowable origin's

Although many pages within Horizon 1.1 leverage the X-Frame-Options header with the recommended SAMEORIGIN policy, some (still popular) older browsers don’t support this setting. Namely, browsers older than IE 8 and Firefox 3.6.9 don’t recognize the header and are thus vulnerable to an attack known as ClickJacking unless an additional mitigating control is present.

To support legacy browsers, a suggested best practice is to add a frame breaking script to the base/global template file. Based off of https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Best-for-now_Legacy_Browser_Frame_Breaking_Script

"""

One way to defend against clickjacking is to include a "frame-breaker" script in each page that should not be framed. The following methodology will prevent a webpage from being framed even in legacy browsers, that do not support the X-Frame-Options-Header.

In the document HEAD element, add the following:

First apply an ID to the style element itself:

<style id="antiClickjack">body{display:none !important;}</style>
And then delete that style by its ID immediately after in the script:

<script type="text/javascript">
   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       top.location = self.location;
   }
</script>

This way, everything can be in the document HEAD and you only need one method/taglib in your API.

"""

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 :

This seems more like a security hardening opportunity, but I'll leave it to the Horizon security reviewers to decide whether they want it kept under embargo and/or a coordinated security advisory published once it's addressed.

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

The assessment on horizon is correct. Horizon is configured with XFrameOptionsMiddleware middleware and by default have a setting of SAMEORIGIN.

Horizon doesn't support IE8 or earlier for past couple of release now.

For reference here is the list of supported browser: https://wiki.openstack.org/wiki/Horizon/BrowserSupport

With that, I agree that this more like a hardening opportunity as the browser version where the issue may occurs are not officially supported.

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

Since it sounds like this is class D (security hardening) or class E (not vulnerable in supported configurations/tools) I'll switch this to public on Thursday unless there are any objections before then. https://security.openstack.org/vmt-process.html#incident-report-taxonomy

Revision history for this message
Brian Tully (brian-tully) wrote :

I have a patch ready to commit for review to support this. Should I wait before I submit it and/or can this be made public since it's considered security hardening and not a vulnerability?

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

Brian, wait until Thursday. If folks agree that it is hardening bug and opened it up to public on Thursday, it should be okay to submit a patch by then.

Jeremy: sounds good to me.

Revision history for this message
Brian Tully (brian-tully) wrote :

Thanks, Lin. Will do :)

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

Agreed it's a class D, opening this bug now

Changed in ossa:
status: Incomplete → Won't Fix
information type: Private Security → Public
Revision history for this message
Brian Tully (brian-tully) wrote :

Tristan - does this need to be opened as a separate bug or can we reuse this bug? I have a patch that I've been waiting to commit until this became public, but now it's marked as "won't fix" so I'm confused as to what the next steps are. Please advise :)

Revision history for this message
Brian Tully (brian-tully) wrote :

ahh nevermind, I see that the "won't fix" was assigned to "ossa" :)

Changed in horizon:
assignee: nobody → Brian Tully (brian-tully)
importance: Undecided → Low
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to horizon (master)

Fix proposed to branch: master
Review: https://review.openstack.org/191591

Changed in horizon:
status: New → In Progress
description: updated
Changed in horizon:
status: In Progress → Fix Committed
Changed in horizon:
milestone: none → liberty-2
status: Fix Committed → Fix Released
Thierry Carrez (ttx)
Changed in horizon:
milestone: liberty-2 → 8.0.0
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.