Opera Widgets security model
24th April 2012: Please note
Starting with Opera 12, Opera Widgets will be turned off for new users and completely removed in a later release. If you're interested in building addons for Opera, we recommend going with our extensions platform — check out our extensions documentation to get started.
Introduction
Opera Widgets can download and combine data from most parts of the Web, which make them a powerful platform for delivering innovative services to users. The security model is initially very open to allow authors to easily create such services. The widget author may change the config.xml
file of the widget in order to restrict the widget’s access to protocols, hosts, and ports.
Note that the security model has changed with Opera 10, mostly by making the model more liberal, but at the same time making network access opt-in. This document describes the latest security model. See the Security model in Opera 9 for the differences and how to cater for both versions.
Table of contents:
- The initial security model
- Form, links and embedded objects behavior
- How to enable network access
- How to enable file access
- Security model in Opera 9
- Controlling the widget’s security
- Examples
- Resources
The initial security model
Network access is not enabled for widgets by default. You must enable this in config.xml to get access.
If network access is enabled and nothing is specified in the security section of the widget’s config.xml
file, the following applies:
- A widget can contact any host over the
http
andhttps
protocols. - A widget cannot contact protocols other than
http
orhttps
, unless specified in itsconfig.xml
. - A widget cannot access the file system using the
file
protocol. - A widget cannot contact non-standard ports (0–1023, except 80), unless specified in its
config.xml
. - A widget can make use of Java applets or plug-ins.
- A widget can access the local file system, but only through a directly user-initiated action.
Note also that many browsers block outgoing HTTP requests on port 443, as this is reserved for HTTPS. Defining access to this port and protocol combination will not work.
Private and public addresses
The following IPv4 IP ranges are defined as private addresses and correspond to the ‘private’ value of the network
property:
- 10.0.0.0 to 10.255.255.255
- 172.16.0.0 to 172.31.255.255
- 192.168.0.0 to 192.168.255.255
- 169.254.0.0 to 169.254.255.255
Any other address is a public address and corresponds to the ‘public’ value of the network
property.
Form, links and embedded objects behavior
Forms, links and embedded objects are subject to the same security policy as loading resources. This means that if the widget contains a clickable link, following the link will result in a security violation if the target of the link is not permitted by the security policy. Similarly for forms, submitting will cause a security violation if the action
attribute contains a URL which is not permitted by the security policy. Objects may not load resources from URLs not permitted by the security policy.
Additionally, the following applies:
- A form element should have a valid target.
- If the form has a reserved target, and this target leads to intrinsically replacing the topmost document in the widget, in effect replacing the widget, submitting the form will fail silently.
- If the form uses the
_blank
target for a GET request, the form will be submitted to a new tab in the browser. - POST requests that result in submission to a tab will fail with a security violation.
- Links have a default
_blank
target, and open in a new tab in the browser. - Objects cannot cross network boundaries when loaded.
- Objects do not share cookies and cache with widgets.
- Objects do not not share cookies and cache with the browser.
- Objects have no reference to
window.opener
(the widget shouldn’t be visible to the object). - The
window.top
property of objects point to the embedding frame only. - Widgets have a one-way reference to inject scripts into and read DOM, etc. from objects.
How to enable network access
From Opera 10 and onwards, network access is opt-in. You can enable network access by adding a network
attribute to the widget
element in the config.xml
file of your widget. This attribute can take one or both of two values, “public” and “private”, which represent public (internet) and private (intranet) addresses respectively.
In the following example, network access for public addresses is enabled:
<widget network="public">
...
</widget>
In the following example, network access for both public and private addresses are enabled:
<widget network="public private">
...
</widget>
How to enable file access
Access to the local file system is enabled by adding a feature
element to the widget
element in Opera 10 and onwards.
<feature name="http://xmlns.opera.com/fileio"/>
By default, the file system can only be accessed through a set of system mount points, called shared
, storage
and application
. The shared
mount point is not available in widgets, but available for Opera Unite services. The application
mount point represents the widget package and the storage
mount point is a scratch space which can be used to store files temporarily. The mount points are mounted through the opera.io.filesystem.mountSystemDirectory()
method.
Additional mount points can only be created by direct user action through the opera.io.filesystem.browseForDirectory()
, browseForFile()
and browseForShare()
methods. When invoked, a file chooser dialogue is raised, and the user must choose a directory to be used as a mount point. Once mounted however, the widget may create, modify and delete files just like the user who runs the widget.
Security model in Opera 9
Opera 9 has a slightly different security model.
- Network access is always on, and can not be opted-out.
- Java and plug-ins are not enabled by default.
https
can not be accessed by default.- Widgets can only access one of private (intranet) and public (internet) addresses. The first host the widget tries to connect to, determines which of the types the widget may access.
To ensure that widgets can be used in both Opera 9 and 10, you should consider adding the following to your config.xml file:
- If your widgets needs network access, add a
network
attribute to thewidget
element with a minimum value ‘public’. Add or use ‘private’ only if necessary, as adding both may leave you vulnerable to data theft. - If your widget needs access to plug-ins, add a
content
element to thesecurity
element withplugins
attributes set to ‘yes’. - If your widget needs access to Java specifically, add a
content
element to thesecurity
element with bothjava
andplugins
attributes set to ‘yes’. - If your widget needs access to
https
, add anaccess
element to thesecurity
element, with twoprotocol
elements containing ‘http’ and ‘https’ respectively.
Additionally, access to the local file system is not supported in Opera 9. In Opera 10, it is enabled by a feature
element. If you wish to use this feature, you should check for the presence of the opera.io.filesystem
property in JavaScript.
If you need all of the features above, your minimal config.xml will look like this:
<widget network="public">
<widgetname>My widget</widgetname>
<feature name="http://xmlns.opera.com/fileio"/>
<security>
<access>
<protocol>http</protocol>
<protocol>https</protocol>
</access>
<content plugins="yes" java="yes"/>
</security>
</widget>
Controlling the widget’s security
You can use the widget’s config.xml
file to limit its access to only specific domains, ports, and protocols. The <security>
element is used for this purpose.
Each <security>
element may contain a series of <access>
elements, which specify what the widget can access. The access
element can contain the following elements:
- protocol
- This specifies the protocols the widget will be using to contact external servers. All protocols except the file:// protocol are permitted.
- host
- The
host
element establishes which hostnames may be contacted. The hostnames are exact matches. This means that a widget specifying www.example.com must not be able to contact example.com. IP addresses may also be used as values. - port
- The
port
element establishes which port numbers the widget will be using. The value is either a number, a range of numbers separated by a dash, eg 1024–2048, or a comma-separated list of ports, e.g. 80, 1337. - path
- The
path
element specifies the path part of the URI that a widget may contact.
If any of these elements are not present, the initial security model provides values for them. This means that any host, ports 80 and 1024 and up, any paths and http
and https
can be contacted. If you add one or more element, this will limit the availability. I.e., if you add a protocol
element, http
and https
will not be available, unless also added.
Examples
Here is a look at a few examples of how the security model and the access
element interact:
<security>
<access>
<protocol>http</protocol>
<protocol>https</protocol>
<host>example.com</host>
<host>example.org</host>
<path>/good</path>
<port>2048-4906</port>
<port>80,1337</port>
</access>
<content plugins="no" />
</security>
In this example, the widget is limited to contacting the hosts example.com and example.org, using either the http
or https
protocols. It may only contact those hosts on ports ranging from 2048 to 4906, and the ports 80 and 1337. The widget may only access the path ”/good” on both hosts. The widget may not use plug-ins or run included Java applets.
Here is a look at another one:
<security>
<access>
<host>example.com</host>
<port>2048-4906</port>
</access>
<access>
<protocol>https</protocol>
<host>example.org</host>
<port>80,1337</port>
</access>
</security>
In this example, there are two primary rules. The widget’s access is limited to example.com and example.org. The widget may only access example.com over the HTTP-protocol and on the ports 2048 through 4906, while example.org can only be accessed over https
and the ports 80 and 1337. In both cases the widget may access any path. The widget may make use of Java applets or plug-ins, which is the default.
And finally:
<security>
<access>
<host>example.com</host>
<port>2048-4906</port>
</access>
</security>
In this last example, the widget may only contact example.com over http
, on any port in the 2048–4906 range, using any path.
Resources
This article is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported license.
Comments
The forum archive of this article is still available on My Opera.