[theora] <video/> and cross site scripting policy.
jonas at sicking.cc
Fri Nov 7 16:42:35 PST 2008
Robert O'Callahan recently asked me to weigh in on the cross-site
Sorry for making this so long. However there seems to be several
misunderstandings floating around, and I want to try to address most of
them as they might affect what we decide on.
== Why restrictions?
It is an absolute requirement from a security point of view that data is
not leaked cross site. We don't want a page on an internet server, lets
call it attacker.com, to read data that lives on an intranet server
behind a firewall, intranet.com.
It is also important that that one site, attacker.com, can't read
personal data stored on other site, bank.com. If it could it would be
possible for any site to read your bank statements as soon as you log in
to your bank.
This is why we for example only allow XMLHttpRequest to make requests to
the same site, but not other sites.
Unfortunately we have inherited a few exceptions to this same-site rule
from the olden, more innocent, days of the internet when security wasn't
as heavily considered. This is why for example <img>, <iframe>, <link
rel=stylesheet>, and <script> can be used cross site.
In all of these cases we try very hard to limit access as much as possible.
For example while you can display another site in an <iframe>, you can't
reach in to the DOM of the page. However click-jacking was recently
discovered which might mean that we'll have to put very complex
restrictions on iframes. Or rely on that sites deploy their own
protections against it. Many probably won't due to not knowing about the
And while you can style your page using a cross site <link
rel=stylesheet> you can't read parse errors since then you could point
to a url of a HTML page that contains sensitive data and potentially get
sensitive information through the parse error messages. We are somewhat
saved here by the fact that it seems very unlikely that someone would
put sensitive data into a stylesheet.
However if someone did, for example a stylesheet setting a background
color to different colors depending on portfolio results in the last
quarter, that data could be read by any site on the internet. Even if
the stylesheet lives on a server protected by firewalls and/or requires
login. This is something that web developers simply has to know. Most
We are in a bad situation with <script> and we have had situations where
sensitive JSON data could be read by pointing a <script> tag at it. The
With <img> we are trying very hard to not expose more than what we can't
prevent. So for example you can get the size of the image (since we
can't prevent that anyway since it affects layout), but you can't get
the pixel data. If we allowed pixel data to be retrieved, again any site
on the internet could read any image data placed on a webserver, even if
protected by passwords/firewalls.
This has prevented the API for <img> to remain unchained for years. And
when we added <canvas> we had to deal with tainting which can cause
confusing behaviors for developers since suddenly certain APIs break. As
roc recently pointed out, pointer-events is another recent expansion of
the browser API which is going to get much harder to implement due to
the unchecked cross-site loading of <img>, and for sure result in that
cross-site images will work differently from same-site images.
== Why not use the same policy as for <img>?
Yes, we could definitely do the same for <video> as we have for <img>.
But it will come with the same downsides. It will mean that we will have
to be much more cautious with how we develop the API for <video>.
There are already discussions about API features that we could not allow
if we allowed cross-site video without Access-Control (or similar)
protection. We would not be allowed to have callbacks for captions where
This would allow an internet site to get captions from board
presentation videos hosted on intranet sites, something that is
obviously not acceptable.
We could say that the captions callback would work, but only if the
video was loaded from same site, or if had the
Access-Control-Allow-Origin:* header set. However this will likely
result in random bugs like captions sometimes failing since the
developer had perfect hearing and so didn't do a lot of testing with
captions. In general accessibility is hard enough to get people to do
correct that I'm reluctant to add features that work great as long as
you don't take accessibility into account, but where you have to take
extra steps to get accessibility to work.
Similar arguments goes for accessing the size of the video file (for
example through progress events). We can not allow that to work for
cross-site loads unless the site has opted in. This is because we likely
won't know that it's actually a video that is being downloaded until
after the first progress events have been fired. This means that you
could use <video> to measure file sizes for arbitrary files that are
otherwise protected by firewalls and/or logins.
If we always restrict usage of <video> to the cases when we know that
the video is private data we will be much more free to develop APIs and
functionality since we won't have to worry about protecting the data
inside it, or deal with error conditions when someone tries to use
sensitive APIs from a cross-site loaded video that didn't have
== It's easier if we don't have any restrictions!
I absolutely 100% agree that it would be easier if we simply allowed
cross-site loading of video. Unfortunately we have to take security into
account as well. Many things would be a lot easier to use if we simply
trusted that people did the right thing and didn't abuse security
problems, or trusted that all server admins that dealt with sensitive
data did the right thing to protect it. However this is rarely the case.
== Enabling Access-Control means that private data is leaked!
I also wanted to correct some misunderstandings in how Access-Control
works. It would be 100% safe for a bank site on the internet to put a
video on their server and send 'Access-Control-Allow-Origin:*' for their
Access-Control has two "modes": public and private. When in public mode
the browser won't send any cookies or authorization headers, or add
anything else to the request that identifies the user. So it knows that
whatever its getting is something that anyone could get using wget. With
the exception for things living on firewalled intranets.
When Access-Control is in private mode it does send cookies and auth
headers as normal. However, it requires that the site adds the header
'Access-Control-Allow-Credentials:true' to the response, otherwise
access to the returned data will be denied. Additionally, in private
mode the '*' value for Access-Control-Allow-Origin is not allowed to
protect against bad caching in proxies.
So if a bank on the internet adds 'Access-Control-Allow-Origin:*' to all
responses, this will never allow user-private bank statements to be read
by other sites.
In other words, deployment of Access-Control for public data is safe for
all servers on the internet. You do not need to separate your private
data from your public data.
It is a bit trickier for intranet sites. This is unfortunate, and the
current version of Access-Control doesn't solve this in an ideal way.
== It'd be really bad if search engines can't search videos!
The policy to require Access-Control does not affect search engines at
all. Requiring that sites add 'Access-Control-Allow-Origin:*' simply is
a way for us to know that "this is a public resource that other sites
can embed". However a search engine knows that all the data it receives
is public. The search engine knows that there is no firewall protecting
the data, if there was it wouldn't be able to reach it. And it also
knows that it's not user private data since it didn't use any cookies or
authorization tokens to fetch it.
To put it another way, search engines and other non-user-run clients are
free to ignore any lack of Access-Control headers. And they probably
would even if we told them not to :)
Sorry again about this long winding mail. And please do let me know if I
have gotten any of the above wrong. I absolutely agree it's not a clear
cut choice. Requiring Access-Control makes it harder to deploy <video>.
But at the same time not doing so is going to make the API more complex
to use for developers as well as implementors. And we never know what
problems we'll run in to in the future, like clickjacking for <iframe>s
or pointer-events for <img>ages.
More information about the theora