Partial security model for Netscape plugins
Version 2 update 2
2006-06-30 / lth


Running scripts from plugins.

Plugin content loaded from domain A (the source domain) wants to run a
script S in the context of a document loaded from domain B (the target
domain).  This is done by A loading the URL javascript:S.

These are the rules:

*  If an OOM or other failure occurs during checking then the check
   fails.

*  If B and S are not both known then the check fails.

*  If A is known, then apply the following rules:

*    If A and B are the same, then the check succeeds.

*    If S matches a database of "safe scripts" then the check succeeds.

*  If A is not known, then apply the following rules:

*    If S matches a database of "intrinsically safe scripts" then the
     check succeeds.

*  Otherwise the check fails.

The set of "safe scripts" and "intrinsically safe scripts" are for 
the time being the same: they include all scripts.  See bug #213716
for why this is necessary, and the section below on a tighter 
definition that did not work out because it did not capture 
sufficiently many scripts.


Safe and intrinsically safe scripts.

The "safe scripts" are those that match the following expression:

  ((window|document|top)\.)?location(\.href)?(\+"__flashplugin_unique__")?;?

with the additional handling of intertoken whitespace and the initial
prefix "javascript:".  The expression must match the entire script,
not just a substring.  

The expression matches this string:

  javascript:top.location+"__flashplugin_unique__"

but it does not match this string:

  javascript:document.getElementsByTagName("input")[0].value

The "safe scripts" represent environment queries.  Technically it is a
breach of the standard security model to allow them to execute
cross-domain, since normal scripts are not allowed to query the
environments of documents from other domains.  However, plugin content
relies on this functionality to a large extent, and plugins are anyway
completely unsafe to begin with.

At this time, the "intrinsically safe scripts" are the same as the
"safe scripts".  The two sets will diverge only if the safe scripts
come to include scripts that may have side effects.

The model chosen here is a compromise between severely restricting
plugins and allowing plugins unrestricted access to other documents.

In a Javascript implementation with getters and setters it may be
possible for a page to define a getter function for window.location,
for example.  A script accessing this property may thus run arbitrary
code.  This risk seems acceptable (and Opera does not have getters and
setters at this time).

The method OpSecurityManager::CheckPluginSecurityRunscript() is called
with the operation PLUGIN_RUNSCRIPT to do the checking.  The source
code S is attached to the target domain B as a text attribute.  The
URL from which S has been extracted must have been unescaped before
checking takes place.


References:
  "Plugin from different host can read cookies for page it is 
  embedded in", https://bugs.opera.com/show_bug.cgi?id=161195

  "Flash loaded from different domain can't access scripts in 
  page", https://bugs.opera.com/show_bug.cgi?id=213716


Changelog

2006-06-30 / lth@opera.com
  Made all scripts "safe", to work around bug #213716.

2006-06-19 / lth@opera.com
  Added references.
  Made the semicolon at the end of the regexp optional.

2006-02-22 / lth@opera.com
  Allowed for the possibility that the URL "A" might not be known by
  introducing "intrinsically safe scripts" and a test for whether "A"
  is known.

2006-02-14 / lth@opera.com
  Created
