[theora] <video/> and cross site scripting policy.

Jonas Sicking jonas at sicking.cc
Fri Nov 7 16:42:35 PST 2008


Hi All,

Robert O'Callahan recently asked me to weigh in on the cross-site 
linking subject.

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 
issue.

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 
probably don't.

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 
way we had to fix this was adding limitations to the javascript language.

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 
the captions are handed to page javascript to be displayed in the page. 
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 
Access-Control-Allow-Origin:*.


== 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 
whole site.

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.

/ Jonas


More information about the theora mailing list