Understanding HTTP header X-Frame-Options - http

Regarding the X-Frame-Options (https://developer.mozilla.org/en-US/docs/The_X-FRAME-OPTIONS_response_header), I'm having a bit of a hard time parsing what the docs say and what I'm seeing. My understanding is that when the page returns SAMEORIGIN, browsers will only load the contents of the frame if the page that had the IFRAME came from the same domain.
I've got three machines. When I'm logged into SERVER-A, I navigate to a page that is hosted on SERVER-A. It contains an IFrame that loads a page from SERVER-B but it's in a different domain. This all works... but when I go to SERVER-C and browse to the same page (that's served from SERVER-A), it won't load. Looking at the IE Debugging Tools, the request for that IFramed page shows a status of aborted.
Ideas?

This is working as you'd expect from server C - you've stated that the iFrame shouldn't load in a page from a different domain in the X-Frame-Options, and it didn't. This security policy isn't applied for pages loaded from localhost, which sounds like it's what's happening here when you're on server A, similarly to this situation.
You haven't said which of the pages you've applied the X-Frame-Options to: it matters that it was on the page in the iFrame (i.e. on Server B in your setup). I don't think applying the header to server A will have made a difference.

Related

Error 302 when the default page is changed in IIS 8

I have the following scenario. I have a website in IIS 8 and I am trying to secure it (https). I have made the web with web forms. In the process to secure it I have to change the page at the beginning (default page in the IIS administrator). When I do it, I don't get the change and I go to the website that was set by default.
I have seen the log and when trying to access the new homepage it gives an error 302 (object moved). I have seen the response header and I see that the location is configured with the old home page.
Example:
Old default page: www.namedomain.com/start.aspx
New default page: www. namedomain.com/home.aspx
The new website has as in the response header: location = /start.aspx and as I said before when trying to access it gives error 302.
Thanks.
There's a few things going on here, "securing" the site with HTTPS and also potentially <authentication mode="Forms"> in your web.config where it will try and redirect any unauthorised requests to a login page. It seems like you are just doing the HTTPS though at this stage, and maybe trying to set up a redirect from HTTP to HTTPS?
It sounds like you are also trying to change the default page for the website (in IIS or the web.config?) from default.aspx to home.aspx? I'm not sure I understand why you want to do that as it isn't necessary for HTTPS, but the effect of that will mean you can go to https://www.namedomain.com/ and you will get served the content from home.aspx instead of start.aspx (or default.aspx) but the URL will stay as just https://www.namedomain.com/
Normally to set up HTTPS, all you do is go into IIS, Bindings, and add a HTTPS binding (you'll need a TLS certificate to make the https work properly). then just make sure you include the "https://" at the start of your URL.
If you think it might be caching problem on your machine, just add a nonsense querystring to the end of your URL (like https://www.namedomain.com?blah=blahblah) and it will cause your browser to get a fresh copy of the page.
I'm not sure what is causing the 302 redirect, have you added any special code to swap HTTP requests over to HTTPS? Can you update your answer with any more info?
Yes, it is what I put in my last comment Jalpa. I do not understand very well the relationship between not configuring the session variables and the default page but once corrected in code, the application correctly loads the web by default.

Last-modified cache does not show when user has logged-in

I am using the last-modified HTTP header to help browsers with caching and I have noticed an annoying problem.
If a user visits a page BEFORE he has logged in, then the browser is showing the cached page even after the user logs-in. This means he is unable to see his log-in information (profile pic, notifications etc) in the header until he visits a page on the site he has not visited before.
Because the content of the actual article itself has not changed since his first visit, he is served up the same page even if he logs-in.
I have tried checking to see if the user has just logged-in (using a SESSION.LoggedIn variable), and then use the current DateTime for Last-Modified, Expires and Cache-Control to tell the browser to serve up a fresh copy of the page but it doesn't work on the Android browser. It just serves the cached version again. What this means is that the user cannot tell that they have logged-in because their name and other credentials don't appear at the top of the page.
How do I use HTTP header caching effectively and also take care of people visiting the same page as both logged-in and anonymously? The logged-in information sits in the header of the site (just like on SO) so is there a way not to cache the siteheader but the rest of the page?
Use a tool like firebug to see the network traffic for a URL. You'll notice that it is 'file' objects: html files, javascript files, css files, images, etc.
I don't think that you can cache a div (or other page layout construct) very easily.
It has been a while since I attempted to use the last-modified HTTP header for caching. I ran into similar problems that you have. Browser implementation/compatibility wasn't 100%. I've also used last-modified in an attempt to inform search engine spiders that files have changed. That didn't work very well either. Eventually I removed all of my attempts at last-modified caching/hinting and just allow the web server and browsers to deal with it.
Eventually I ended up spending a lot of time optimizing database queries, database indexes, and in a few cases implemented the cachedwithin attribute of cfquery tags. This attempt at improving site performance has worked better for me.

Server returns 404 for a web page, but page is showing fine in browser - why?

A strange web page crossed my way. (And being a developer I have to solve the mystery.)
When accessing the web page in any browser, all seems normal. The web page is displayed as expected.
But when looking in the console the server acually returns a 404 status code:
So why is the browser rendering a page?
Looking at the Body shows valid HTML is returned:
Hold on. Responding 404 and sending the HTML along the way? And the browser renders it??
Why is this happening? Is this some server misconfiguration? Or is something clever going on here that I don't understand? Is there a practical reason for configuring a server on purpose to behave like this?
Another answer on Stack Overflow contains some interesting information: A HTTP status code of 404 plus HTML response body is actually recommended by the spec.
The 4xx class of status code is intended for cases in which the
client seems to have erred. Except when responding to a HEAD
request, the server SHOULD include a representation containing an
explanation of the error situation, and whether it is a temporary or
permanent condition. These status codes are applicable to any
request method. User agents SHOULD display any included
representation to the user.
This leaves me with two possible explanations:
Explanation 1: it's a server error.
the server wrongly returns a 404 status code
the browser thinks the response body contains details about the error and displays it - for the end user this is the actual page
Explanation 2: it's done on purpose to defeat crawlers and page watchers.
the server returns 404 on purpose - non-browser user agents won't process the result as they interpret it as error
browsers are unaffected, the end user doesn't care as long as the page is being displayed
The second one would indeed be kind of clever if you don't want your page to be indexed.
I faced with the same situation. My portal was hosted in a tomcat server. The portal was loaded when the host name along with the tomcat directory path was hit. But on loading the the webpage redirected to a deep-link URL and rendered the page. But if you hit the deep link URL directly in the browser it would give you 404 error in the network tab in Dev tools although the webpage would be rendered fine.
This happens because there is no resource as your deep-link URL anywhere in your server config files, so when it searches for the resource it doesn't find one and returns 404 in the network tab in Dev tools.
But browser behaves differently with the resource URL. It first loads and connects to the host name of the resource, when returned with success gets redirected as per the config files settings and renders the deep-link URL resource HTML, styling contents properly.
Note: I don't know whether this issue comes from me not being strict enough in the .htaccess or my CMS.
In my contrived .htaccess example I had the following rules to ignore these directories from being handled by the CMS.
RewriteCond $1 !^(branch|css|js|html|images) [NC]
I also had a branches directory inside my CMS' templates (created within CMS). I guess my .htaccess rule wasn't strict enough here. I had to change branch to branch\/, like so:
RewriteCond $1 !^(branch\/|css|js|html|images) [NC]
Only then would the page load without the 404 in the console.

Secure IFRAME nested on non-secure page

I have a client that, due to specific reasons, needs to place an IFRAME pointing to an HTTPS page on an HTTP page. The HTTP page is hosted on a different domain and server than the HTTPS page, but are both owned by the same client.
Putting aside the reasons why this should not be done, I am finding it difficult to implement in practice.
As one can see on this page: http://www.clevelandutilities.com/obppay.htm there is a HTTPS IFRAME on an HTTP page without any warnings from the browser (Firefox OR IE). However, if I try the same method, both Firefox and IE complain about the certificate.
Any ideas on why that is? I've examined the source at that sample site and can see nothing special being done, yet if I try the same thing I get squawking. Further, if I put the domain that they are using (https://www.paybill.com/cu/), it doesn't complain - if I put our domain it, it complains. Are all SSL certificates created equal?
To boil it down, this works without warnings:
<iframe src="https://www.paybill.com/cu/" width="100%" height="600" scrolling="auto"></iframe>
this does not:
<iframe src="https://www.myclientdomain.com/somepage.php" width="100%" height="600" scrolling="auto"></iframe>
Further, we use an IFRAME-style Facebook app to pipe in to this same HTTPS page, and THAT works with no complaints about the SSL certificate. Huh?!
After digging a bit, we uncovered that the certificate is specific to www.myclientdomain.com, and the developer in charge had used ...src="https://myclientdomain.com"... in the IFRAME. This was causing the following "Connection is untrusted" error screen:
The common practice for the host domain is to never use 'www' in the URL (enforced with .htaccess), whereas the standard for the source domain (the one with the certificate) is to always use it (enforced with .htaccess). That's what lead the other developer to leave it off - that's what he is used to for his site.
If one clicked "I understand the risks" even once for the source domain and added the certificate exception, any visit thereafter would have made it to the htaccess and be redirected to www-, which is why on my (and the other developer's) computer the page would load fine and check out normal in Firebug while our boss got the warning. We had both (apparently) added the exception for one reason or another in the past.
When we put it together, it was a real facepalm moment. Thanks to anyone who had given this question thought, sorry to have not checked the details carefully enough. :)

How Can I Bypass the X-Frame-Options: SAMEORIGIN HTTP Header?

I am developing a web page that needs to display, in an iframe, a report served by another company's SharePoint server. They are fine with this.
The page we're trying to render in the iframe is giving us X-Frame-Options: SAMEORIGIN which causes the browser (at least IE8) to refuse to render the content in a frame.
First, is this something they can control or is it something SharePoint just does by default? If I ask them to turn this off, could they even do it?
Second, can I do something to tell the browser to ignore this http header and just render the frame?
If the 2nd company is happy for you to access their content in an IFrame then they need to take the restriction off - they can do this fairly easily in the IIS config.
There's nothing you can do to circumvent it and anything that does work should get patched quickly in a security hotfix. You can't tell the browser to just render the frame if the source content header says not allowed in frames. That would make it easier for session hijacking.
If the content is GET only you don't post data back then you could get the page server side and proxy the content without the header, but then any post back should get invalidated.
UPDATE: 2019-12-30
It seem that this tool is no longer working! [Request for update!]
UPDATE 2019-01-06: You can bypass X-Frame-Options in an <iframe> using my X-Frame-Bypass Web Component. It extends the IFrame element by using multiple CORS proxies and it was tested in the latest Firefox and Chrome.
You can use it as follows:
(Optional) Include the Custom Elements with Built-in Extends polyfill for Safari:
<script src="https://unpkg.com/#ungap/custom-elements-builtin"></script>
Include the X-Frame-Bypass JS module:
<script type="module" src="x-frame-bypass.js"></script>
Insert the X-Frame-Bypass Custom Element:
<iframe is="x-frame-bypass" src="https://example.org/"></iframe>
The X-Frame-Options header is a security feature enforced at the browser level.
If you have control over your user base (IT dept for corp app), you could try something like a greasemonkey script (if you can a) deploy greasemonkey across everyone and b) deploy your script in a shared way)...
Alternatively, you can proxy their result. Create an endpoint on your server, and have that endpoint open a connection to the target endpoint, and simply funnel traffic backwards.
Yes Fiddler is an option for me:
Open Fiddler menu > Rules > Customize Rules (this effectively edits CustomRules.js).
Find the function OnBeforeResponse
Add the following lines:
oSession.oResponse.headers.Remove("X-Frame-Options");
oSession.oResponse.headers.Add("Access-Control-Allow-Origin", "*");
Remember to save the script!
As for second question - you can use Fiddler filters to set response X-Frame-Options header manually to something like ALLOW-FROM *. But, of course, this trick will work only for you - other users still won't be able to see iframe content(if they not do the same).

Resources