Firefox3.1/External SVG References Security Review
The goal is to allow cross-document references in SVG to work. In particular, it should be possible to reference paint servers, masks, and so forth across documents, as well as allowing <use> to work across documents.
- The bug tracking this work is https://bugzilla.mozilla.org/show_bug.cgi?id=433616
- Design notes:
- The external resource documents must have a frame tree for this to work correctly. I have ended up creating content viewers for the external documents to manage the frame tree, presshell, and so forth.
- To avoid issues related to navigating resource documents and scripting them, docshells and windows are NOT created for the external resources.
- External resource documents need to be able to load various subresources (stylesheets, images, etc), but we disallow loads of subframes, plug-ins, and scripts via content policy. We also disable the script loader.
- Disallowing subframe loads is not sufficient to prevent creation of parent-less docshells for nsSubDocumentFrame, so we explicitly forbid this in resource documents in the frameloader.
- Disallowing plug-in loads is not enough to prevent plug-in instantiation, so we explicitly disallow this in nsObjectFrame.
- To reduce attack surface, while we will StartDocumentLoad whatever we get back from the server, we will immediately abort the load if the resulting document is not being parsed via a parser, or is using a content sink that doesn't implement
nsIXMLContentSinkor QIs to
nsIXULDocument. This prevents non-XHTML HTML and prototype-based XUL from being used as external resources. It's still possible to use XHTML (with either its MIME type or generic XML type) or XUL inside an XHTML or generic XML document.
Security and Privacy
- The main security issue inherent here is that we're changing various invariants (e.g. allowing a presshell to not have a docshell), and that we're creating a new type of parent-less documents, one that allows layout and various sub-resource loads. I have audited the various callsites of nsIDocument and nsPresContext methods that get windows and containers and fixed a number of issues that would have turned into null-dereference crashes. We also guard better against thinking that XUL is in a toplevel document when it actually isn't.
- These changes increase attack surface somewhat, since all sorts of features can now be used in this new external resource context. I have done a good bit of code-auditing and some testing, but some things remain to be tested (e.g. XBL). Fuzzing of the whole setup would probably be beneficial
- For now (3.1) we will restrict external SVG to same-origin
- If we expand this in the future we will use Access-Control
- which site would we send in a complex tree? Doc A could reference svg docs B and C, both of which include svg from X. We only load one copy of X, which Origin: do we send?
- script must be disabled in these external documents.
- don't ever "fix" these to have a docshell -- the lack of one is the implicit basis for the security here. With a docshell we'd have to do a lot more explicit security checks.
- if a parent document clones nodes from the external document "onfoo" event-handling attributes get cloned too, effectively importing scripts. How do we stop this? Or at least force the importing document to explicitly request this behavior?
- <script> nodes could be imported by cloning, perhaps accidentally if the parent doc is blindly importing a subtree. In normal DOM cloning the "hasExecuted" flag would be set and cloned, but since we're cloning from a script-less context that's probably not the case here and the script will execute on insertion.