According to The Web Origin Concept (RFC 6454), a regular origin consists of the triple (uri-scheme, uri-host, uri-port)
. Since the data URI scheme does not equal with the HTTP URI scheme, and the URI it describes certainly does not have the same host and port as your web application has, it is obvious that your data URI has a different origin.
I created a sample code in php:
http://test.loc/
Returns aaa
in a HTTP response.
aaa
http://test.loc/x.html
Sends GET http://test.loc/
and displays aaa
in the body if not blocked by CORS.
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', "http://test.loc", true);
xhr.onreadystatechange = function (){
if (xhr.readyState==4)
document.body.innerHTML = xhr.responseText;
};
xhr.send();
</script>
http://test.loc/y.php
Loads the http://test.loc/x.html
script from a data URI.
<object
data="data:text/html;base64,<?php echo base64_encode(file_get_contents('x.html')); ?>"
></object>
Results:
- msie does not support data URIs currently
- firefox always displays
aaa
- chrome display
aaa
only if I setAccess-Control-Allow-Origin: null
, otherwise it runs the script in a sandbox, and hides the XHR response from it
Conclusion:
Currently only chrome supports CORS with data URIs in a proper way. We should send a bug report to mozilla, because this is a security issue. Javascript sent in a data URI can avoid regular js filters...
After 3 years:
According to my bug report by Firefox, the specs are changed, so they fixed this. So data URIs require the allow origin header now on every browser where they are supported.