Author Topic: [RESOLVED] x_frame_options and ALLOW-FROM URL  (Read 15740 times)

Offline jmanko

  • Jr. Member
  • **
  • Posts: 11
[RESOLVED] x_frame_options and ALLOW-FROM URL
« on: October 15, 2014, 02:44:15 PM »
I have two options regarding x_frame_options.

1. In which file do I set $rcmail_config['x_frame_options']?

2. What are the valid values for that option?  I'd like to only allow a specific domain to iframe load (sphere.mydomain.com), which differs from my roundcube domain (cube.mydomain.com)

« Last Edit: October 15, 2014, 04:30:41 PM by jmanko »

Offline jmanko

  • Jr. Member
  • **
  • Posts: 11
Re: x_frame_options
« Reply #1 on: October 15, 2014, 03:16:45 PM »
Almost got it. 

I added the following to ./config/config.inc.php:
Code: [Select]
$config['x_frame_options'] = 'ALLOW-FROM https://sphere.mydomain.com';
The page now loads, but I get an Roundcube Javascript-generated warning message and I'm unable to log in (fields disabled):
Code: [Select]
Blocked: possible clickjacking attack!
I changed the configuration to add a colon, as indicated by the spec, but I just get a white page again:
Code: [Select]
$config['x_frame_options'] = 'ALLOW-FROM : https://sphere.mydomain.com';
Spec:
http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-01

Code: [Select]
The header field name is:
   X-Frame-Options

   There are three different values for the header field.  These values
   are exclusive, that is NOT more than one of the three values MUST be
   set.

   DENY
         A browser receiving content with this header MUST NOT display
         this content in any frame.

   SAMEORIGIN
         A browser receiving content with this header MUST NOT display
         this content in any frame from a page of different origin than
         the content itself.
         If a browser or plugin can not reliably determine whether the
         origin of the content and the frame have the same origin, this
         MUST be treated as "DENY".
         (Please note that current implementations may vary on the
         interpretation of this criteria: In some it only allows to be
         framed if the origin of the top-level browsing-context is
         identical, in other it compares with to the origin of the
         framing page.)

   ALLOW-FROM  (followed by a URI [RFC3986] of a trusted origin)
         A browser receiving content with this header MUST NOT display
         this content in a frame from any page with a top-level browsing
         contex of different origin than the specified origin.  While
         this can expose the page to risks by the trusted origin, in
         some cases it may be necessary to allow the framing by content
         from other domains.
         For example: X-FRAME-OPTIONS: ALLOW-FROM:
         https://www.domain.com/

   The ALLOW-FROM URI MUST be valid.
   Any data beyond the domain address (i.e. any data after the "/"
   separator) is to be ignored.  And the algorithm to compare origins
   from [RFC6454] SHOULD be used to verify a referring page is of the
   same origin as the content or that the referring page's origin is
   identical with the ALLOW-FROM URI.

   Wildcards or lists to declare multiple domains in one ALLOW-FROM
   statement are not permitted.

   Please note that in conflict with [RFC6454], current implementations
   do not consider the port as a defining component of the origin.

Offline jmanko

  • Jr. Member
  • **
  • Posts: 11
Re: x_frame_options
« Reply #2 on: October 15, 2014, 04:29:13 PM »
I found a work around for this, and I also filed a issue:
http://trac.roundcube.net/ticket/1490100

./program/js/app.js (replace app.min.js with this):
Code: [Select]
    // clickjacking protection
    if (this.env.x_frame_options) {
      try {
        // bust frame if not allowed
   
        if (this.env.x_frame_options == 'deny' && top.location.href != self.location.href) {
          top.location.href = self.location.href;
        } else if (this.env.x_frame_options.indexOf('ALLOW-FROM') == 0) {
   
        } else if (top.location.hostname != self.location.hostname) {
          throw 1;
        }
      } catch (e) {
        // possible clickjacking attack: disable all form elements
        $('form').each(function(){ ref.lock_form(this, true); });
        this.display_message("Blocked: possible clickjacking attack!", 'error');
        return;
      }
    }