Multiple X-Frame-Option refuses to show in-frame - php

I have an awful situation
A website with Apache2+Php5.6, one of the pages of the site has a <iframe> tag but it refuses to load because X-Frame-Options was set in more than one php file inside the web archives with differentes values (DENY and SAMEORIGIN) falling to DENY.
Refused to display 'webpage' in a frame because it set multiple 'X-Frame-Options' headers with conflicting values ('DENY, SAMEORIGIN'). Falling back to 'deny'.
I try to set X-Frame-Option in security.conf or with .htaccess but when the page use that particular file, it overrides the value and finish into the same situation.
Refused to display 'webpage' in a frame because it set multiple 'X-Frame-Options' headers with conflicting values ('SAMEORIGIN,DENY, SAMEORIGIN'). Falling back to 'deny'.
My questions
¿Is there a way to override all response headers of my page?, or
¿Is it posible to find in which php file X-Frame-Option was set?
I know that is posible to disable X-Frame-Option but i don't want that if there is any other posible solution or workaround.
Thanks in advance
UPDATE
It was a nginx server working as reverse proxy in top of my configuration with that property settet to DENY, hoppefully i manage to reach that configuration and now it work perfectly

You can check the response headers in the Network tab in developer tools to check which responses come with which X-Frame-Options value.
You can override X-Frame-Options in modern browsers by specifying Content-Security-Policy frame-ancestors directive in a response header. Use Content-Security-Policy: frame-ancestors 'self';

Related

X-Frame-Options not explicitly set to sameorigin, but Nginx blocking rendering page into iframe

I did not explicitly set anywhere in nginx the x-frame-options to sameorigin but nginx is blocking the html page rendered inside an iframe. Tried specifying the domain in the X-Frame-Options but no luck. Giving several errors in the console if that helps. I read through them and tried fixes but not working.
https://preview.codecanyon.net/item/product-name/product-id
It previews my HTML page in an iframe.
The problem is not about X-Frame-Options but Content-Security-Policy also. Codecanyon set an CSP header that prevent the other sites can frame in their site. Even you allow all sites in your XFO header, they can block your site display in their website with CSP header.
But they are a market, they have to open a way for developer to include an iframe in their preview page. Seems they're not implemented a way for developer provide frame-src in preview page. So Codecanyon's CSP header is in Report only mode. All things is running fine although a lot of error you see from Chrome Developer Console.
By the way, you implemented an syntax error CSP header: unexpected punctuation at the start.
If it helps, I later figured out that setting frame-ancestors to that specific domain allowed that domain to show the page in an iframe. You can do that in the nginx config file.

Blocked a frame with origin from accessing a cross-origin frame in wordpress

I am working on a website, let say the website name is "https://website" (which is built on wordpress) in which I am getting the following error on console:
Uncaught DOMException: Blocked a frame with origin "https://website" from accessing a cross-origin frame.
at contents (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,utils,underscore,wp-util,backbone,&load%5B%5D=moxiejs,plupload&ver=4.9.8:2:26921)
at Function.map (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,utils,underscore,wp-util,backbone,&load%5B%5D=moxiejs,plupload&ver=4.9.8:2:3613)
at a.fn.init.n.fn.(anonymous function) [as contents] (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,utils,underscore,wp-util,backbone,&load%5B%5D=moxiejs,plupload&ver=4.9.8:2:27001)
at b (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=postbox,thickbox,hoverIntent,common,admin-bar,wp-a11y,updates,plugin-install,svg-painter,heartbeat,wp-auth-check,shortcode,wp-ba&load%5B%5D=ckbone,media-models,wp-plupload,wp-mediaelement,wp-api-request,media-views,media-editor,media-audiovideo,mce-view,imgareaselect,&load%5B%5D=image-edit&ver=4.9.8:347:103)
at HTMLBodyElement.<anonymous> (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=postbox,thickbox,hoverIntent,common,admin-bar,wp-a11y,updates,plugin-install,svg-painter,heartbeat,wp-auth-check,shortcode,wp-ba&load%5B%5D=ckbone,media-models,wp-plupload,wp-mediaelement,wp-api-request,media-views,media-editor,media-audiovideo,mce-view,imgareaselect,&load%5B%5D=image-edit&ver=4.9.8:347:1306)
at HTMLBodyElement.dispatch (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,utils,underscore,wp-util,backbone,&load%5B%5D=moxiejs,plupload&ver=4.9.8:3:12444)
at HTMLBodyElement.r.handle (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,utils,underscore,wp-util,backbone,&load%5B%5D=moxiejs,plupload&ver=4.9.8:3:9173)
at Object.trigger (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,utils,underscore,wp-util,backbone,&load%5B%5D=moxiejs,plupload&ver=4.9.8:3:11573)
at Object.a.event.trigger (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,utils,underscore,wp-util,backbone,&load%5B%5D=moxiejs,plupload&ver=4.9.8:9:8275)
at HTMLDivElement.<anonymous> (https://website/wp-admin/load-scripts.php?c=1&load%5B%5D=jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,utils,underscore,wp-util,backbone,&load%5B%5D=moxiejs,plupload&ver=4.9.8:3:18991)
The above error is generated by clicking View Details section of wordpress plugins (as shown below):
This error seems to exist in every single wordpress plugins but it works when I open in a new tab but it doesn't work when I open in the same window.
Problem Statement:
I am wondering which file I need to modify in wordpress in order to solve this error. This error seems to exist in every wordpress plugins. As mentioned, it works in a new tab but fails to work in the same page.
I have a feeling I have to make some changes in the following file by seeing the error above (load-scripts.php, as the error is generated in that file) but not sure what line I need to add in order to make it work.
https://website/wp-admin/load-scripts.php
Something bad has happend to your WordPress admin interface.
The first thing to notice is that the error you have described is a well known problem as you may have already noticed: SecurityError: Blocked a frame with origin from accessing a cross-origin frame
Look at the first answer there:
You can't access an with different origin using JavaScript,
it would be a huge security flaw if you could do it. For the
same-origin policy browsers block scripts trying to access a frame
with a different origin.
Protocol, hostname and port must be the same of your domain, if you
want to access a frame.
The second thing to notice is what the "View details" button in the WordPress admin interface does: It opens a ThickBox containing and iframe which is showing remote contents quite often within an IFrame. How this works is ecactly described here: https://codex.wordpress.org/Javascript_Reference/ThickBox
load-scripts.php is an important WordPress core file loaded in the admin which is used to load JavaScript files without having to embed each of them. Those JavaScript files are usually added to your WordPress admin with the admin_enqueue_scripts() function (https://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts).
As your problem is quite uncommon and the "View details" button for Plugins works almost everytime there are only two possibilities:
1. The "View Details" IFrame is usually loaded from the same location where your WordPress is - therefore you might have a problem such that the browser wants to load it from a different host
This happens if you have some misconfiguration within your WordPress installation and Thickbox tries to get an IFrame from a host which the Browser thinks is another host. Configure WordPress correctly.
2. You have a badly programmed plugin or theme which is injecting a script causing this problem
Solution: Deactivate your theme and all your plugins one-by-one and see if the error still exists. This way you can find out the modification which causes the problem and maybe do a bug request to the plugin developers then.
It is almost 100% sure that a single plugin, theme or misconfiguration is causing this problem.
For posterity, chances are your X-Frame-Options have either been set to deny by the server or a configuration was appended by another plugin, but the blocked frame issue may happen when your server has not been configured correctly or was configured with strict policies to prevent any sort of access to cross-origin frames. Since every plugin is affected when viewing the Details link, my answer coincides with what #Blackbam has explained regarding how it functions by bringing up a thickbox and uses an i-frame when explaining why they all don't seem to appear.
I am wondering which file I need to modify in WordPress in order to
solve this error. This error seems to exist in every wordpress
plugins. As mentioned, it works in a new tab but fails to work in the
same page.
So, for this particular case I don't believe it's necessarily a WordPress issue but a hosting server configuration and, depending on how much access you have to the server or wherever you're building the website, will determine what you can do to solve this error or whether or not you'll need to contact support to help you resolve it.
(Since this answer is simply added for posterity, please excuse the present tense references used as I realize it's been 3 years since this was asked)
Solutions:
There are two options that may work for you, and will vary depending on your server and your user access.
Solution 1: Adding permissions by modifying the .htaccess file
If your webhosting server is running on Apache or other supported web server, you can try adding the lines below to the .htaccess file:
<ifModule mod_headers.c>
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
Header always set X-Frame-Options "sameorigin"
Header setifempty Referrer-Policy: same-origin
</ifModule>
For syntax, you can refer to to this page. But as another option, instead of setting X-Frame-Options to "sameorigin" you can also specify a particular domain so as to preserve the security feature if preferred, such as:
Header always append X-Frame-Options "ALLOW-FROM website.com/*"
And replacing "website.com/*" with the domain you would like to permit, noting the space between ALLOW-FROM and the URL as further explained here. If you have other plugins installed that have modified your .htaccess file, be sure to place this entry above any Wordpress created entry as the .htaccess file is loaded in order and also note that it may not be supported in all browsers. Now, depending on the server security policies, if this doesn't work, then you'll have to move on to the next solution.
Solution 2: Modify your server configuration
Though I'm only including instructions for an Apache server from here as reference, this page includes configurations for Nginx, IIS, HAProxy, and Express as well. A full explanation can be found here if you have access to WHM and/or are running virtual servers and will require root access.
Log into the web server and look for the following file:
/etc/apache2/conf/httpd.conf
# or you can also create a new file named 'include.conf' if it
# doesn't already exist
/etc/apache2/conf.d/userdata/{USERNAME}/{DOMAIN-NAME}/include.conf
If the file exists, you can either comment out the line if it's set to DENY to disable the restriction or add the line below to the newly created configuration file:
<ifModule mod_headers.c>
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
Header always set X-Frame-Options "sameorigin"
</ifModule>
You'll then need to rebuild the configuration and restart the Apache server.
You can rebuild by running the command
/usr/local/cpanel/scripts/rebuildhttpdconf
Then restart with
/usr/local/cpanel/scripts/restartsrv_httpd
Without the same-origin setting, even though Wordpress is installed on the server, the jquery requests are being blocked as part of preventing any embedding of content from other sites as well. Read more about Secure Headers from OWASP

The 'Access-Control-Allow-Origin' header has a value that is not equal to the supplied origin

I am trying to login with ajax to an API and I get this error:
XMLHttpRequest cannot load. The 'Access-Control-Allow-Origin' header
has a value that is not equal to the supplied origin. Origin
'http://localhost' is therefore not allowed access.
I read all about this error, all over the internet, and I've tried all the solutions I could find online. I modified the .htaccess and apache httpd configuration file according to the CORS instructions here: http://enable-cors.org/server_apache.html
Access-Control-Allow-Origin: *
Nothing seems to be working. I'd really appreciate if you guys can help me out with this. Thank you!
You have to set Access-Control-Allow-Origin header to * or specified value http://localhost
You can do this through:
1- Your code
2- .htaccess file
3- Server config (restart web server required)
Here is the link that show how to do it on apache
http://access-control-allow-origin-guide.com/enable-cors-on-apache-linux/
As added browser security, unless the API allows cross-browser origins in the the return responses header there is no way around this.
The browsers are blocking it, there is a plugin to allow for chrome but it is not realistic to depend on browser plugin to allow end user requests,
Try and reach out to the API provider and see if they can look into updating the header in the response.
It is a CORS issue:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
i use htaccess file for load JSON data in different hosting, and its works but
it have to put inside the public html root of our web hosting for example
uploading .htaccess into --> (https://freehostingsomewhere.com/)
then inside .htaccess
<FilesMatch "\.(ttf|otf|eot|woff|jpg|png|jpeg|gif|js|json|html|css)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://localhost"
</IfModule>
</FilesMatch>
in here i use http://localhost to development and it works,
maybe if i have another web host just change it into that url, i will try it later (it can, i already try it) :p
this is just for more clear explanation
cheers :p
Are your requests using either cookies or authorization by any chance?
Check on your ajax call on the client side if you're configuring it to be done "with credentials"
.withCredentials = true;
If yes, the wildcard(*) will not work and you'll need to provide the exact host as the value for Access-Control-Allow-Origin.
Refer to this stack overflow answer or Mozilla Documentation on CORS

Apache2 Headers not working correctly

Having issues with iframes (have no control as these come with the system I have) and the cross-site stuff.
Have added the usual X-Frame-Options to my .htaccess file to include the directive to allow it to allow the iframe from this other system that wants to iframe the site. No problem at first.
<IfModule mod_headers.c>
Header always set X-Frame-Options "ALLOW-FROM https://otherhost"
</IfModule>
And I can confirm that the above is taking effect as I have messed with the header content and it is reflected.
For some reason, I keep seeing the header X-Frame-Options ALLOW-FROM https://otherhost, SAMEORIGIN with this additional SAMEORIGIN, which of course is not valid and fails within the browsers, ultimately resulting in the browser falling back to DENY, which then means the iframe is not shown.
The apache2 specs states for the set option, that;
The response header is set, replacing any previous header with this name. The value may be a format string.
Yet I do not see it replacing the string. If I curl the login page, it presents correctly, if I inspect it in the chrome/safari inspector, it shows the additional , SAMEORIGIN and then complains that it's not valid.
I've even tried using the unset option for the Header directive, but it still keeps producing this header.
Is the Header directive post or pre output? as this is driving me nuts and wasting so much time for a simple thing.

How to get grade A on these Yslow rules?

Use a Content Delivery Network (CDN)
Compress components with gzip
Configure entity tags (ETags)
Add Expires headers
If i don't have access to Apache configuration.
Use a Content Delivery Network (CDN)
This involves changing your hosting (for at least some files)
Compress components with gzip
Configure entity tags (ETags)
Add Expires headers
You can either:
Get access to your Apache configuration
Get someone who does have access to it to change it
I find "HOW TO SPEED UP YOUR SITE AND GET A YSLOW GRADE" is useful for me. Hope this help.
If you have grade A on every other YSlow rule then you're doing pretty well already and don't need to worry about those items. By the way, you can create custom rulesets in YSlow that are more tailored to your needs and server setup. So if you can't change any of these things, just remove them from the rules that YSlow uses.
Use a Content Delivery Network (CDN)
You can add your site domain as a CDN in YSlow. The idea of this one is to store static components on different domains to increase "parallelisation" (downloading more files at once). If you are using limited hosting then you could open a separate account and host some files there on a different domain.
Compress components with gzip
You can do this in PHP, using ob_start('ob_gzhandler'); at the very start of your scripts. This is a little more resource intensive so use Apache if possible.
Configure entity tags (ETags)
Remove this from the rule list, it's not necessary in 90% of cases. Yahoo only says to remove them because in the rare situation you have multiple servers in the back-end, the same file might have a different ETag if it comes from a different server. When each file comes from one server then ETags are a good thing and removing them is detrimental.
Add Expires headers
If you have no access to the server then you probably won't be able to change this. Ask your host about it. You may be able to override the server setting in your .htaccess file. You'd need the mod_expires Apache module. This page has some usage examples.
Paste this code bottom of .htaccess file
RewriteEngine On
# BEGIN Mod Header
ExpiresActive On
# Turn on Expires and set default expires to 10 years
# END Mod Header
# BEGIN Cache Control
Header set Expires "Thu, 15 Apr 2012 20:00:00 GMT"
Header unset ETag
FileETag None
#END Cache Control

Categories