Same origin policy / CORS in MVC 5 - asp.net-mvc-5

What is the default policy within an asp.net mvc application? Also how are CORS and X-Frame-Options related?
If I create a new MVC web app (hosted in IIS) on port e.g. 21232, I add an iframe to the index views with a source set to my local IIS e.g.
<iframe src="http://localhost/iisstart.htm" width="800" height="100"/>
This works fine (even though on a different port to the web application).
If I now change the iframe source to be something completely external, e.g.
<iframe src="http://www.google.com" width="800" height="100"/>
This now displays an empty iframe. If I look in the Chrome dev tools (Chrome used in both examples) I see an error in the console
Refused to display 'https://www.google.co.uk' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.
Why did the first URL work when the address is on a different port to the hosting page?
How do X-Frame-Options relate to CORS? I tried adding the following to my web.config (see ref enable cors in IIS)
<add name="Access-Control-Allow-Origin" value="*" />
Which made no difference. Looks as if I need to add the following to the Application_Start in the global.asax.cs
AntiForgeryConfig.SuppressXFrameOptionsHeader = true;
Are X-Frame-Options specifically iframe related?

I think you got the The X-Frame-Options response header and CORS all mixed up.
The X-Frames-Options response header is used to indicate whether or not a browser should be allowed to load a particular page in a <iframe>. CORS on the other hand is used to determine if XMLHttpRequest(XHR) (and a few other things) is allowed across domains.
So yes, X-Frames-Options are <iframe> realated only.
The reason why you are able to load your page from http://localhost/iisstart.htm in you web application running at port 21232 is because there is no X-Frame-Options response header present in response. You will not be able http://www.google.com because its X-Frames-Options is set to SAMEORIGIN. This means unless your domain is google.com, you will not be able load it inside an <iframe>.
The Access-Control-Allow-Origin header that you added has nothing to do with <iframe>. There is no way you will be able to load http://www.google.com in your page.

Related

How to Use eTag on IIS for text/html Pages

I have a website which sits on a non-public domain and is delivered via a proxy through on a different domain. We're having some trouble with caching of content - this is an Umbraco site and making changes updates the pages if you hit the domain directly, but not through the proxy.
I've been informed that the proxy honours response headers and setting an eTag would fix the issue. Having looked into this I can see that IIS sets the eTag by default, and I can see this is working on static content i.e. .js, .css files like so:
However, if I visit a page on the site, for example /uk/products/product I don't see the eTag header.
Is this expected behaviour, should it only be working with those static content files or can I set this on the page to tell the proxy that it should recache?
The ETag HTTP response header is an identifier for a specific version of a resource. It lets caches be more efficient and save bandwidth, as a web server does not need to resend a full response if the content has not changed. Additionally,etags help prevents simultaneous updates of a resource from overwriting each other ("mid-air collisions").
If the resource at a given URL changes, a new Etag value must be generated.
Static content does not change from request to request. The content that gets returned to the Web browser is always the same. Examples of static content include HTML, JPG, or GIF files.
IIS automatically caches static content (such as HTML pages, images, and style sheets), since these types of content do not change from request to request. IIS also detects changes to the files when you make updates, and IIS flushes the cache as needed.
to enable caching in iis you could use iis output caching feature:
1)open iis manager. select site.
2)select the output caching feature from the middle pane.
3)select edit feature setting from the middle pane.
4)check the enable cache and enable kernel cache box and click ok.
if you want to set the ETag as blank you could also do by adding below code in web.config file:
<httpProtocol>
<customHeaders>
<add name="ETag" value="" />
</customHeaders>
</httpProtocol>
refer this below article for more detail:
Caching
To use or not to use ETag, that is the question.
Configure IIS Output Caching
I've read that IIS after version 7 automatically enables E-tags, however, I ran a Pingdom speed test and the report advised me to enable E-tags. I'm not sure that report is accurate, or the information I read about IIS 7 and newer may not be correct.

Is it possible to only allow CORS from one website only and not directly?

Suppose I have a web application at origin.com. When I browse origin.com it request cross-site data from datafeed.origin.com. I have following written in .htaccess of datafeed.origin.com Header set Access-Control-Allow-Origin origin.com. Everything works perfectly till this point.
What I need is protect datafeed.origin.com. How can I prevent this domain from browsing directly from browser or any other application. Only allow access when cross referencing from origin.com.
You can specify the origin when setting the Access-Control-Allow-Origin header:
Access-Control-Allow-Origin: <origin>[, <origin>]*
Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
Looking at your post it looks like you've done this, so cross origin requests should fail from other domains

What is globally adding an "x-frame-options: deny" header?

I have a client who uses ColdFusion 10 and IIS 7.5 on Win 2k3 R2. The ColdFusion admin uses frames. When I log into the CF admin I'm seeing a blank white screen in Chrome and in IE I am seeing a message telling me this:
This content cannot be displayed in a frame
To help protect the security of information you enter into this website, the publisher of this content does not allow it to be displayed in a frame.
I see a few of this message (1 for each frame) in the chrome dev console:
Refused to display 'http://localhost/CFIDE/Administrator/navserver.cfm' in a frame because it set 'X-Frame-Options' to 'DENY'.
Looking at the response headers in Chrome, I can see that this is set to DENY.
I can't figure out where this is coming from. All of the sites on this server now are outputting this header. I never explicitly configured anything to output this header. I know CF wouldn't have done so in a patch because it would break its own admin interface.
IIS's root server-wide configuration HTTP Response Headers doesn't have a X-Frame-Options set and neither do any of the configured websites.
If I explicitly add an X-Frame-Options header and set it to sameorigin I see both headers (deny and sameorigin).
Is there perhaps some software the client's security team might have installed that would be injecting this header?
I'm accessing the site on localhost so I can't imagine that it's a network device causing the problem. It must be on the server itself, right?
Any ideas?
This could be set within ColdFusion, assuming it's been locked down. Look in
(instancename)/wwwroot/WEB-INF/web.xml for the rules around clickjack. Might look something like this:
<filter-mapping>
<filter-name>CFClickJackFilterDeny</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Another way to test to see if this is being caused by IIS is to set up a frame sample with straight HTML pages and if it works the block is at the ColdFusion level. If straight HTML does not work then it is happening at IIS or some other server location.
In IIS, HTTP Response Headers can be set server-wide (affecting all sites) and/or site-wide (affecting only the current site).
Reading your question again, I see I may not have helped you. Good luck.

IIS 8.5 Not honoring Web API [EnableCors] attribute. Not setting Access-Control-Allow-Origin Header

Rundown
So I've continued tinkering with this. This is a new Windows Server with IIS 8.5. I've never had any problems getting CORS to "just work" in IIS so I've never really needed to care about the fiddly bits in the server config. The immediate fix was the shotgun approach; I enabled CORS server-wide with the following modification to applicationhost.config
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
but removing this customHeader and setting [EnableCors(origins: "*",headers: "*", methods: "*")] inside my controllers does not cause the server to send back Access-Control-Allow-Origin response headers (yes, I made sure to call config.EnableCors() in my HttpConfiguration.
An additional complication is that using this method, I have to allow all origins because I need several origins to be able to access this server. Browser implementations do not permit multiple origins to be sent back from the server in this header. I could always write my own EnableCors logic within my application, but would rather understand and fix the server config to stay on the res.
Original Question
So I'm running into a bit of an issue trying to get a Web Application deployed to IIS 8.5 on a fresh Windows Server 2012 R2 straight from our server provisioning team. My application is a Web API with Cors Enabled, (currently allowing all origins) but the server is not returning an Access-Control-Allow-Origin header to calling clients. I've never had an issue with Web API Cors "just working."
I found this resource, but confirmed that the OPTIONSVerbHandler had already been removed within my application's web.config.
I tried to add a customHeader to IIS, but whenever I did that, the server started returning 500s.
Is there anything that I can do to force IIS 8.5 to send Access-Control-Allow-Origin headers from ASP.NET?
Edit1
So I apparently installed the ASP.NET Cross Origin Resource Sharing NuGet package into my solution rather than the ASP.NET Web API 2.2 Cross Origin Resource Sharing NuGet package. I swapped these out and I have limited (but still unexpected) CORS functionality. I'll describe the weirdness I'm experiencing now.
So before I realized I had the wrong NuGet package, I had gone into applicationHost.config and added
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
in an attempt to get the server to push the header back manually. Without the NuGet update, this did not set the header on preflight responses but at this point I'm not quite sure if that was due to me forgetting an iisreset;I was trying to move fast.
At any rate, when I added the Web API 2.2 Cors NuGet package, my server responses started emitting an Access-Control-Allow-Origin header with wildcard origins rather than the ones that I had set in my EnableCors attributes inside my Web API routes. So with that value, I knew that it was the configured customHeader rather than the EnableCorsAttribute that is now controlling the value.
(Here's where the weirdness comes in)
So I would actually prefer to be able to directly control the CORS whitelist directly at the server level, so I went ahead and set the customHeader to
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://segment.mydomain.com" />
</customHeaders>
where http://segment.mydomain.com also matches one of the allowed origins inside my API routes.
I now get the proper Access-Control-Allow-Origin sent back from IIS in the PreFlight request, but the subsequent POST returns a 500. If I remove the EnableCors attribute from my Api Route, the POST succeeds (confirmed by directly querying the database that persists the posted data)
...wt*?
Edit2
So that hopeful approach (statically defined origins inside a customHeader in IIS rather than allowing developers to list their origins directly inside controllers) won't actually work. I need to whitelist multiple origins and Chrome's implementation only allows one origin to be set in the ACAO header. It also will not allow wildcard segments in origins, so...that sucks.

Tracking down X-Frame-Options header

We've partnered with a company whose website will display our content in an IFRAME. I understand what the header is and what it does and why, what I need help with is tracking down where it's coming from!
Windows Server 2003/IIS6
Container page: https://testDomain.com/test.asp
IFRAME Content: https://ourDomain.com/index.asp?lots_of_parameters,_wheeeee
Testing in Firefox 24 with Firebug installed. (IE and Chrome do the same thing.) Also running Fiddler so I can watch network traffic while I'm at it.
For simplicity's sake, I created a page with nothing on it but the IFRAME in question - same physical server, different domain/site - and it failed with
Load denied by X-Frame-Options: https://www.google.com/ does not permit cross-origin framing.
(That's in the Firebug console.) I'm confused because:
Google is not referenced anywhere in the containing app, or in the IFRAMEd app. All javascript libraries are kept locally; there is no analytics in the app. No Google, nowhere.
The containing page has NOTHING on it, except the IFRAME. No html tags, no head tag, no body tag. IFRAME. That's it.
The X-FRAME-OPTIONS header does not exist in IIS on the server: not at the "Websites" node, not in the individual sites.
So where the h-e-double-sticks is that coming from? What am I missing?
Interesting point: if I remove http"S" from the IFRAME url, it works. Given the nature of the data, SSL is required.
You might check global.asax.cs, the app could be adding the header to every response automatically. If you just search the app for "x-frame-options" you might find something also.

Resources