I'm creating a script, that embed iframe with my site to client's site, but I want to limit access to this feature.
I added 2 headers to the server responses
Content-Security-Policy: "frame-ancestors: example.com"
X-Frame-Options: ALLOW-FROM example.com
It works, but X-Frame-Options doesn't support multiple domains, so I added a GET-param to the iframe URLs, that contain frame ancestor URL
And when http://example.net requests mysite.com/embed/?from=http://example.net I check the whitelist and send this domain in headers
My problem is obtaining a real page origin, that browser uses to compare with the headers.
I tried location.origin and document.referrer but both return wrong values when I request iframe from iframe.
For example http://jsbin.com. I can't find way to obtain real URL in sandboxed code, it's always http://null.jsbin.com. But for Content-Security-Policy a browser uses http://jsbin.com/
Related
Suppose if my domain is A and I want to display an image from domain B I can do this successfully by placing the image URL from B in the src attribute of the img tag on my website and expect the picture to display. However when I try to display the image on a canvas and convert it to base64 using the toDataUrl function I am unable to do so due to CORS reasons.
My questions are - How come I get to display the image from domain B if it does allow cross origin resource sharing? Is it only a HTTP header setting on domain B that must be configured in order to allow my domain A to access the resource or is there a setting on domain A that needs to be activated as well?
CORS doesn't place any restrictions. The Same Origin Policy places restrictions. CORS can remove some of them.
There is no restriction on displaying images.
<img alt="" src="//cross-origin.example.com/foo.jpeg"> is absolutely fine (although the site could attempt to defeat that by testing the referer header with server side code).
By default, JavaScript is prevented from accessing the data inside the image (e.g. placing the image on a <canvas> and then generating a data: URL from it which the JavaScript could then pass on to the server).
CORS can lift that restriction with an Access-Control-Allow-Origin header.
Is it only a HTTP header setting on domain B that must be configured in order to allow my domain A to access the resource...
Yes, to indicate to the browser that it's safe for the origin domain B gives permission to to use the image, for instance:
Access-Control-Allow-Origin: https://domaina.example
Depending on how the image is being retrieved, it may need further headers to allow credentials or headers, but that's the main one.
Domain A doesn't need anything special, just code using the image data.
Full details in the specification.
I have a site that host some public content: https://secure.example.com/PublicContent.html. I am rendering it through an iframe on an unsecured site: http://public.example.com. I have both pages setting document.domain = "example.com";.
If I load public.example.com using HTTPS, I can have the iframe resize correctly using the onload attribute:
onload="this.style.height = this.contentWindow.document.body.scrollHeight + 'px';"
However, if I load public.example.com without HTTPS, I get Access is denied. Any ideas how to get this to work on HTTP?
Not possible if you're using this.contentWindow
Same-origin policy: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
Two pages have the same origin if the protocol, port (if one is specified), and host are the same for both pages.
To share information between the same domain no matter which protocol used, you might want to take a look at cookies. https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Cross-origin_data_storage_access.
Also, used this lib to solve a similar issue: https://github.com/davidjbradshaw/iframe-resizer
Is it possible to load an external website in iframe but without sending HTTP_REFERER ? I just don't want be tracked.
If it is possible then how and if not then is there any workaround using divs or anything else ?
For anchor tag with external link jQuery("a").attr('rel','noreferrer'); is working, but for iframe I've failed to make it work.
Is there any script( js or jQuery ) to make it work ?
Here's a very simple solution.
Use this in you document <head> tag and you are good to go :D
<meta name="referrer" content="none">
The meta referrer tag is placed in the <head> section of your HTML,
and references one of five states, which control how browsers send referrer information from your site.
The five states are:
None: Never pass referral data
None When Downgrade: Sends referrer information to secure HTTPS sites, but not insecure HTTP sites
Origin Only: Sends the scheme, host, and port (basically, the subdomain) stripped of the full URL as a referrer, i.e. moz.com/example.html would simply send moz.com
Origin When Cross-Origin: Sends the full URL as the referrer when the target has the same scheme, host, and port (i.e. subdomain) regardless if it's HTTP or HTTPS, while sending origin-only referral information to external sites. (note: There is a typo in the official spec. Future versions should be "origin-when-cross-origin")
Unsafe URL: Always passes the URL string as a referrer. Note if you have any sensitive information contained in your URL, this isn't the safest option. By default, URL fragments, username, and password are automatically stripped out.
Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
I came across this on MDN stating that setting the referrerpolicy attribute to no-referrer would accomplish this.
Example:
<iframe src="https://www.whatismyreferer.com/" referrerpolicy="no-referrer"></iframe>
For example, the first search result on this page leads to the older SO question, with the following HTTP request:
GET /questions/4402502/how-does-google-set-the-http-referrer-when-someone-clicks-on-a-search-result-lin HTTP/1.1
Host stackoverflow.com
Referer https://www.google.ru
Note, that:
Only the domain is included in the Referer header, no query string.
Google is open via HTTPS, while SO is open via plain HTTP - nevertherless, the Referer header is sent by the browser.
There are no server-side redirects involved, the first HTTP query to open after the click is to the target site.
The question is, how do they achieve this?
Google makes use of Referrer Policy.
They include the meta tag in the page:
<meta name="referrer" content="origin">
This tells browsers to use "Origin Only" policy, that is, to send domain only information in the Referrer header in any subsequent request.
When we need to invoke an Ajax request we do :
if(typeof XMLHttpRequest !== 'undefined') xhr = new XMLHttpRequest();
else
{
var versions = ["Microsoft.XmlHttp",
"MSXML2.XmlHttp",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.5.0"
];
I already know that using XMLHttpRequest-2 ,we can make a cross origin request AND that the ORIGIN header is added.
Question:
When does this header added ?
Is it added when a browser (that support CORS) is performing a request ? ( cross domain or non-cross-domain?)
Or is it added automatically when the browser "sees" that the request target origin is different from the current origin...
I mean : what the He** does the bold line mean ?
Cross-origin HTTP requests have an Origin header. This header
provides the server with the request’s origin. This header is
protected by the browser and cannot be changed from application code.
In essence, it is the network equivalent of the origin property found
on message events used in Cross Document Messaging. The origin header
differs from the older referer [sic] header in that the referer is a
complete URL including the path. Because the path may contain
sensitive information, the referer is sometimes not sent by browsers
attempting to protect user privacy. However, the browser will always
send the required Origin headers when necessary.
The Origin header
When this header is added ?
During the header's stage, before the document's body is sent (after open, before send).
Is it added when a browser (that support CORS) is doing a request ? ( cross domain or non-cross-domain?)
It is added when the origin doesn't match the page from which the XMLHttpRequest is created, but may also be sent in a same-origin request.
Or does it added automatically when the browser "sees" that the request target origin is different from the current origin...
Yes.
However, the browser will always send the required Origin headers when necessary.
This is part of the XMLHttpRequest spec; if you're making a cross-domain request, in the request headers an extra header is sent. This header is e.g. Origin: http://www.stackoverflow.com and is appended by a standards-following browser without user interaction.
You can read more on the specification in MozillaWiki's Security section, WHATWG and html5.org. It is implemented by (that I know of) FireFox and Google Chrome. I don't believe it is part of W3C yet. Further do not assume the origin header is true, as it can be set manually by modified borwsers or other software.
The origin header is added automatically (generally) when you do a cross domain request.
To test it, I opened the console on this page and made two different requests: one for another domain and one for '/' and just the first got the origin header added.
BTW, I'm using JQuery for it and I'd really advise you to use it too in order to have the same behavior cross-browser.
For complementary info on the subject, check this:
The first thing to note is that a valid CORS request always contains
an Origin header. This Origin header is added by the browser, and can
not be controlled by the user. The value of this header is the scheme
(e.g. http), domain (e.g. bob.com) and port (included only if it is
not a default port, e.g. 81) from which the request originates; for
example: http://api.alice.com.
The presence of the Origin header does not necessarily mean that the
request is a cross-origin request. While all cross-origin requests
will contain an Origin header, some same-origin requests might have
one as well. For example, Firefox doesn't include an Origin header on
same-origin requests. But Chrome and Safari include an Origin header
on same-origin POST/PUT/DELETE requests (same-origin GET requests will
not have an Origin header).
Source