This document includes material copied from the W3C Working Draft of the Runtime and Security Model for Web Applications specification from 21 March 2013.
Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
This document specifies a runtime and security model for Web Applications. It describes how an application is defined through an application manifest, and how it can be installed, updated and packaged. It also specifies how such an application can be put into the background, be put back in the foreground or woken up. Finally, the document describes the security model for such applications. This includes the permission model and the different security rules that would apply.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document defines a runtime and security model for Web Applications, along with a manifest format and packaging model. The current draft covers the use of CSP policies for trusted packaged applications, and future drafts will extend this to trusted hosted applications.
This specification is being republished as a Working Group Note as an indication that it not being progressed further as a Recommendation track document.
This document was published by the System Applications Working Group as a Working Group Note. If you wish to make comments regarding this document, please send them to [email protected] (subscribe, archives). All comments are welcome.
Publication as a Working Group Note does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 August 2014 W3C Process Document.
The EventHandler interface represents a callback used for event handlers as defined in [HTML5].
The concept of fire a simple event is defined in [HTML5].
The terms event handlers and event handler event types are defined in [HTML5].
The DOMError interface represents an error handling object as defined in [DOM4].
An application manifest is a JSON file describing an installable web application. This JSON file consists of a top-level object and several properties. The JSON grammar is described in [RFC4627].
{ "name": "The Example App", "description": "Exciting Open Web development action!", "launch_path": "/", "version": "1.0", "icons": { "16": "/img/icon_16.png", "48": "/img/icon_48.png", "128": "/img/icon_128.png" }, "developer": { "name": "Foo Corp.", "url": "http://sysapps.org/example" }, "appcache_path": "/cache.manifest", "locales": { "es": { "description": "¡Acción abierta emocionante del desarrollo del Web!", "developer": { "url": "https://sysapps.org/example/es-ES" } } }, "default_locale": "en", "screen_size": { "min_width": "600", "min_height": "300" }, "required_features": ["touch", "geolocation", "webgl"], "permissions": { "contacts": { "description": "Required for auto-completion in the share screen", "access": "read" } }, "fullscreen": "true", "relNotes": { "1.0": "Bugs fixed. New exciting effects. Ready for an official release!", "0.5": "First alpha version with still some bugs but already fun!" } }
Any new specification can add new properties to the application manifest. Those specifications MUST describe the new properties, the expected values and the expected behaviour. Implementations MUST implement the basic properties as describe below but SHOULD only implement any extented feature if they are implementing those specifications.
All leaf properties MUST contain a string value unless specified otherwise.
The following properties MUST be part of the application manifest:
name
and description
. In
addition, if locales
is part of the application manifest,
default_locale
MUST be part of the application manifest. The other
properties are optional.
min_height
and
min_width
properties that describe the
minimum height and width (in pixels) the application
needs in order to render correctly. Those values are only
hint for the UA and should not be considered as mandatory
restrictions.Each specification MUST specify the new permissions that would be required to use the feature it is defining.
The application's origin is the origin of the application manifest. [ORIGIN]
An application manifest MUST be served from the same origin as the application.
When served as a static file, it is RECOMMENDED that the manifest is
stored with the extension .webapp
. The manifest
MUST be served with a
Content-Type header of
application/x-web-app-manifest json
. It is
RECOMMENDED that
application manifests are served over SSL.
Application
interfaceWeb Applications are represented by the Application
interface.
interface Application {
readonly attribute DOMString origin;
readonly attribute Object manifest;
readonly attribute DOMString installOrigin;
readonly attribute unsigned long installTime;
readonly attribute Object parameters;
DOMRequest
launch ();
DOMRequest
uninstall ();
readonly attribute DOMString updateState;
readonly attribute unsigned long downloadSize;
DownloadRequest
downloadUpdate ();
readonly attribute DOMString state;;
void hide ();
void exit ();
attribute EventHandler onlaunch;
attribute EventHandler onpause;
attribute EventHandler onresume;
attribute EventHandler onterminate;
};
downloadSize
of type unsigned long,
readonlyinstallOrigin
of type DOMString, readonlyinstallTime
of type unsigned long,
readonlymanifest
of type Object, readonlyonlaunch
of type EventHandler,onpause
of type EventHandler,onresume
of type EventHandler,onterminate
of type EventHandler,origin
of
type DOMString,
readonlyparameters
of type Object, readonlyinstall()
in ApplicationRegistry
.
state;
of
type DOMString,
readonlyrunning
if the
current application state is running. Otherwise, if the current
application state is paused, it MUST return paused
.
Otherwise, it MUST return terminated
.
updateState
of type DOMString, readonlyavailable
, downloading
,
downloaded
or installing
,
depending on the state of the application.installing
.downloaded
.downloading
.available
. Otherwise, the attribute
MUST return the
empty string.downloadUpdate
DownloadRequest
object and asynchronously run the following steps:
InvalidState
and abort these steps.
DownloadRequest
exit
void
hide
void
launch
DOMRequest
instance
and then run the following steps asynchronously:
error
event to the DOMRequest
object with the "NotAllowedError"
error code and exit those steps.
success
event to
the DOMRequest
object and set result
to null.error
event
to the DOMRequest
object with an error code that describes the
error.
DOMRequest
uninstall
DOMRequest
instance
and then run the following steps asynchronously:
error
event to the DOMRequest
object
with the "NotInstalledError"
error
code and exit those steps.
error
event to the DOMRequest
object
with the "NotAllowedError"
error code
and exit those steps.
success
event
to the DOMRequest
object
and set result
to null.error
event
to the DOMRequest
object with an error code that describes the
error.
DOMRequest
The following are the event handlers (and their corresponding
event handler event types) that
MUST be supported as
attributes by the Application
objects:
event handler | event handler event type |
---|---|
onlaunch |
launch |
onpause |
pause |
onresume |
resume |
onterminate |
terminate |
DownloadRequest
interface
interface DownloadRequest : DOMRequest
{
void cancel ();
attribute double progress;
attribute EventHandler onprogress;
};
onprogress
of type EventHandler,progress
of type double,error
the
attribute MUST
return 0.0. Otherwise, if the current state is
success
, the attribute MUST return 1.0. Otherwise, the
attribute SHOULD return the current progress of the
download expressed between 0.0 and 1.0.cancel
UserCancel
.
void
When the caller start
the download, the DownloadRequest
SHOULD start downloading the
resource.
If the resource fails to download, the UA MUST send an error message to the request.
If the resource succeed to download, the UA MUST send a success message to the request.
While the resource is downloading, which means as long
as readyState
is pending
, the UA
SHOULD regularly
fire a simple event named
progress on the object. The UA should note that
sending too much events might have an impact on performance
but sending too few of them might impact the user
experince.
The following are the event handlers (and their corresponding
event handler event types) that
MUST be supported as
attributes by the DOMRequest
objects:
event handler | event handler event type |
---|---|
onprogress |
progress |
ApplicationRegistry
interfaceThe ApplicationRegistry
interface allows handling applications and query there
status.
interface ApplicationRegistry {
DOMRequest
install (DOMString manifestUrl, [Optional] Object parameters);
DOMRequest
getSelf ();
DOMRequest
getInstalled ();
DOMRequest
checkInstalled (DOMString manifestURL);
attribute ApplicationManagement
management;
};
management
of type ApplicationManagement
,ApplicationManagement
object.
checkInstalled
DOMRequest
object
and asynchronously check if there is an installed
application in the system with a manifest URL
matching manifestURL.success
event to the DOMRequest
object
and populate its result
attribute with
the boolean value true if there is an installed
application fulfilling the condition, otherwise
result
should be set to false.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
manifestURL |
DOMString |
✘ | ✘ |
DOMRequest
getInstalled
DOMRequest
object
and asynchronously get all applications that have an
origin matching the caller's origin. [ORIGIN]success
event to the DOMRequest
object
and populate its request
attribute with
an array containing the applications.
DOMRequest
getSelf
DOMRequest
object
and asynchronously get all applications that have an
origin matching the caller's origin. [ORIGIN]success
event to the DOMRequest
object
and populate its request
attribute with
an array containing the applications.
DOMRequest
install
DOMRequest
instance
and then run the following steps asynchronously:
error
event to the DOMRequest
object with the "NotAllowedError"
error code and exit those steps.
manifestUrl
.success
event to
the DOMRequest
object and set result
to null.error
event
to the DOMRequest
object with an error code that describes the
error.
The UA SHOULD verify at any moment before
installing that manifestUrl
points to a
valid manifest. If this is not the case, the UA
MUST fire an
error
event to the DOMRequest
object
with the "InvalidArgumentError"
and exit
the steps.
The UA SHOULD save the parameters
if some are passed so they can later be retrieved by
the parameters
attribute on the Application
interface.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
manifestUrl |
DOMString |
✘ | ✘ | |
parameters |
Object |
✘ | ✘ |
DOMRequest
ApplicationManagement
interfaceThe ApplicationManagement
interface allows access to all applications and is being
informed any time an application is being installed or
uninstalled. The intent of this interface is to be
restricted to privileged callers.
interface ApplicationManagement {
DOMRequest
getAll ();
[TreatNonCallableAsNull]
attribute EventHandler oninstall;
[TreatNonCallableAsNull]
attribute EventHandler onuninstall;
DOMRequest
applyUpdate (Application
application);
};
oninstall
of type EventHandler,AppObject
of the application that was
installed.onuninstall
of type EventHandler,AppObject
of the application that was uninstalled.applyUpdate
InvalidState
and abort these steps.
Application
object
representing the updated application as a value.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
application |
|
✘ | ✘ |
DOMRequest
getAll
DOMRequest
object
and asynchronously get all applications currently in
the application registry.success
event to the DOMRequest
object
and populate its request
attribute with
an array containing the applications.
DOMRequest
An install event MUST be fired on all ApplicationManagement
instances as soon as an application is installed.
The uninstall event MUST be fired on all ApplicationManagement
instances as soon as an application is uninstalled.
The following are the event handlers (and their corresponding
event handler event types) that
MUST be supported as
attributes by the ApplicationManagement
object:
event handler | event handler event type |
---|---|
oninstall |
install |
onuninstall |
uninstall |
Application Events are sent when an event happen on the application level like an application being installed or uninstalled.
[Constructor(DOMString type, Application eventInitDict)]
interface ApplicationEvent : Event {
readonly attribute Application
application;
};
application
of type Application
,
readonly
dictionary ApplicationEventInit : EventInit {
Application
application;
};
ApplicationEventInit
Membersapplication
of type Application
ApplicationEvent
objects
MUST contain a non-null
application
attribute representing the
application on each the action happened.
The application events are always sent asynchronously, do not
buble and are not cancelable.
There are currently two types of Application Events:
application
MUST represent the
installed application.application
MUST represent the
uninstalled application.A packaged application is an application that is self-contained in a container. All resources that are commonly used by the application SHOULD be available in the container.
A hosted application is an application that is not a packaged application
This section is non-normative.
A packaged application would be useful in a few situations, amongst them:
An application manifest for the application MUST be present at the root of the container.
The container of a packaged application MUST be a ZIP file.
A file contained in a packaged application MUST have an URI with the following rules:
scheme
of the URI MUST be app.authority
of the URI MUST be an identifier unique
for each applications. That means, two files from different
applications can't share the same authority
but two files from the same application will.path
of the URI MUST be the file name.For more information about URI's, refer to [RFC3986].
For example, the URI of index.html from an application can be: app://e35b8412-7451-46e7-ab29-0cee24fd486a/index.html.
The URI of a packaged file is defined such as two files
from the same packaged application MUST share the same origin.
A file from a packaged application and any other resource
outside of this application (an application or not, packaged
or not) MUST not share
the same origin. [ORIGIN]
A packaged application MUST have a copy of its application manifest outside of the package so it can be used for installation and updates purposes. As a consequence, that copy of the application manifest can be reduced to only a few properties: name, version and relNotes. In addition, a new property can be used only in the content a packaged application manifest: package that SHOULD contain an object with the following properties:
{ "name": "My Packaged App", "description": "This is my first packaged app!", "launch_path": "/", "version": "1.0", "developer": { "name": "Mozilla", "url": "https://mozilla.org/en-US" }, "package": { "url": "http://example.org/mypackagedapp.zip", "size": "1024", "sha256": "6df134b0cfd88d6d4f27a99e29b9923d50eb8b2c0d5289c60012de424c7a9d97" } }
An application SHOULD advertise an update by updating its application manifest.
The UA SHOULD regularly check if the application manifest of installed applications has not been updated. To know if the file has been updated, HTTP semantics apply.
For package applications, both application manifests (outside and inside the package) SHOULD be updated. However, the application manifest inside the package SHOULD always be checked to make sure the update (or the install) is genuine.
In the context of a running application, all usual rules for data isolation MUST apply: same-origin policy, same-domain policy, or whatever is used. However, between two applications, those rules no longer apply. Two applications MUST be fully isolated from each other in the sense that they SHOULD NOT be able to access data from each other. For example, if App1 accesses http://example.org and gets a cookie from it, App2 should not be able to see that cookie when accessing http://example.org even if the usual cookie sharing policy should allow this to happen.
This isolation SHOULD apply for all data storage like
cookies, localStorage, IndexedDB, app
cache and any other Web Platform mechanism that allows to
store data and doesn't explicitly opts out from the application
data isolation.
The isolation SHOULD
also apply to UA specifics data storage. For example, any
permission granted or denied to a host/origin/domain should be
isolated per-application or auto-fill and autocompletion
features for forms.
System Messages are events sent by the system to an
application which has registered for it before. Those events
are different from DOM events in the sense that they are always
originated by the system and that if the targeted application
isn't currently running, it will be started.
In addition, un-handled messages will stay in a queue.
This section is non-normative.
Some applications might be interested in getting some
events even if they are not running and want to be woken up
if such events is sent while they are asleep.
In addition, when the application is being woken, it needs to
know as soon as possible why it has been disturbed to be able
to show the appropriate interface.
Finally, the capability of being woken should be transparent
to the application.
The type of system
message identifies a category of system messages.
Application are be able to register and handle system
messages based on their types. There is no exhaustive list of
system messages type. Any specification can create a new type
of system message.
Each application has a pool
of messages for each type of system message. Everytime a
system message is sent to an application, if there is no
handler for that message's type, the UA MUST add the message to the pool of
messages used for that type.
The UA MAY, for memory
optimization, discard old messages if the pool becomes too
big or if the messages are too old.
When a UA is required to fire a system message of a given type, it has to do one of these actions:
This section is non-normative.
Some API might allow the application to access sensitive parts of the hardware or sensitive information. To prevent applications to access them, some APIs might require one or more permissions. For example, for an application to be allowed to access your geolocation information, it has to be granted the geolocation permission.
An application SHOULD define all permissions it is going to use in the application manifest. The UA MAY automatically grant some permissions at install-time or ask the user to grant some applications. However, MAY, in addition or alternatively, ask the user to grant permissions at run-time.
The user MUST be able to revoke a granted permission or grant a denied permission at any time.
Specifications are expected to declare the permissions they will require for their feature to work. Altough, some basic permissions can't really go into a specific specification or a related to specifications that might be harder to change.
Thus, this specification is defining the following permissions:
Permission Name | Permission Description | Access Type |
---|---|---|
desktop-notification |
Allow the application to use the Desktop Notification API. | N/A |
geolocation |
Allow the application to access the Geolocation API. | N/A |
storage |
Allow localStorage and IndexedDB without size limitations. | N/A |
webapps-manage |
Allow access to the
navigator.apps.management API to manage
installed webapps. |
N/A |
This section is non-normative.
Any application can be compromised. It just depends on how much effort the attacker wants to provide and how much efforts the author wants to dedicate making its application more secure. With an interesting enough outcome, attackers could easily double their efforts to beat the security in place. For example, an API allowing to send SMS, if it can be manipulated by the evil persons, could be used to send premium SMS and steal money from the users.
With a simple permission system, users could be tricked to install the application and accept to grant the application the relevant permissions. These kind of attacks are proven to be efficient.
An application is said to be a trusted application if the origin installing the application is trusted by the UA and the origin installing the application consider the application as trusty.
A UA SHOULD have the public key of all installation origin it is considering trusted.
A hosted application MUST be recognized as marked trusted by the installation origin if the application manifest is signed by the installation origin's private key.
A packaged application MUST be recognized as marked trusted by the installation origin if the package is signed by the installation origin's private key.
In both cases, the application SHOULD be considered as trusted by the UA if the UA considers the installation origin as trusted, following the chain of trust mentioned above.
This section is non-normative.
UA should keep in mind that a signed package is way more secure than a signed manifest. A correctly signed package can only be compromised if the private key has been compromised or the cryptographic algorithm. A UA should not trust an installation origin if it does not trust its ability to keep safe its private key.
On the other hands, a signed manifest only proves that the application is genuinly trusted (if the private key was not compromised nor the cryptographic algorithm). Anything else can be compromised given that it lives in the Internet. There is no need to list all possible attacks.
An important difference between a packaged application and a hosted application is the ability to review the code. Any permission granted to a packaged application will be granted to the code inside the package only. That means trusting such application is way easier after a code review, for example.
However, code review for packaged applications could be
avoided if the installation origin trusts enough an
application developer. Such developer could get all its
packaged applications trusted
without too much risk for the users.
The same thing colud be done for hosted application except that it would
be recommended to make sure that the developer has strong
server security or would not risk any security flaw on
their servers.
The following CSP policy MUST apply to all trusted applications
[CSP]:
default-src *; script-src 'self'; object-src
'none'; style-src 'self'
This puts the following restrictions on web pages part of a trusted application:
This does not restrict any of the following:
There is no way for trusted applications to relax this policy.
At any time, an application MUST be in one of the following states: running, paused, terminated.
An application is running when it has been launched by the UA and has not been put in paused. A running application can transition to paused or terminated states.
If a running application transitions to a
paused state, the UA MUST fire a simple event named
pause
on the Application
object before
switching its state.
If a running application transitions to a
terminated state, the UA MUST fire a simple event named
terminate
on the Application
object before shutting
down the application.
An application is paused when the UA stops the execution of an application without terminating it. A paused application SHOULD have all its scripts no longer running, such as rendering, parsing, processing media files and any action that requires CPU and memory or would distract the user. A paused application can transition to running or terminated states.
If a paused application transitions to a
running state, the UA MUST fire a simple event named
resume
on the Application
object after changing
its state.
An application is terminated when the application has been stopped and is no longer loaded in the system. The state of a terminated application can only be changed to running if the application is launched again.
If a terminated application transitions to
a runningstate, the UA MUST fire a simple event named
launch
on the Application
object after the main
browsing context is created but before the load
and DOMContentLoaded
events are fired.
The specification currently assumes that one will save important when paused so there is no terminate event when transitionning from pause to terminate.
Do we have real use cases for launch
?
Is firing before load
a hard thing to do?
While an application is running, it can be part or fully hidden. The visibility events described in [PAGE-VISIBILITY] MUST be sent when the visibility status of the application changes.
In addition, when the application becomes fully hidden, the UA MAY put the application in a paused state.
DOMRequest
interfaceThe DOMRequest
interface is
temporarily hosted by this specification. The Runtime
and Security Model for Web Applications specificaton
doesn't plan to keep that guest for ever, this is why it is
currently staying in an appendix.
This section is non-normative.
Some methods want to return a value or do an action but
can't do it synchronously, most of the time for performance
reasons. In that case, most of those methods will use a
callback mechanism to inform the caller of the success or the
failure of the action.
However, this callback mechanism makes the code barely
readable and there is no common pattern used by all API in
the Web Platform.
DOMRequest
intend to be used
instead of those callbacks to make those APIs more
developer-friendly and help code readability.
The DOMRequest
interface is intented
to be used by asynchronous methods that want to return
something after performing an action or simply want to inform
the caller that the action is done.
It returned request can also be used to inform that an error
happened during the operation.
A DOMRequest
has three state. It is
whether pending
, success
or
error
.
The initial state of a DOMRequest
MUST be pending
.
If a DOMRequest
receives a
success message while in the
pending
state, its state MUST change to success
and
SHOULD NOT change
afterward.
If a DOMRequest
receives an
error message while in the
pending
state, its state MUST change to error
and
SHOULD NOT change
afterward.
If a DOMRequest
receives a
success message or an error message while not in the
pending
state, the message MUST be ignored.
A success message
SHOULD be sent to the
DOMRequest
when the
operation is successfuly terminated. The message MAY contain a value which
MUST be used by the
result
attribute. If the message does not
contain a value, null MUST be used instead.
As soon as a success message is received,
readyState
MUST return done
,
result
MUST return the received value or null as
explained above and the object MUST NOT change its state and MUST, therefore, ignore all
following success message and error message.
Finally, the UA MUST
fire a simple event named
success
on the object
An error message
SHOULD be sent to the
DOMRequest
when the
operation has failed. The message MAY contain a value which MUST be a DOMError object and MUST be used by the error
attribute. If the message does not contain a value, the UA
SHOULD find the most
appropriate DOMError that represents the failure.
As soon as an error message is received,
readyState
MUST return done
, error
MUST return the
received value the most appropriate error value as explained
above and the object MUST NOT change its state and MUST, therefore, ignore all
following success message and error message.
Finally, the UA MUST
fire a simple event named
error
on the object.
interface DOMRequest : EventTarget {
readonly attribute DOMString readyState;
readonly attribute any result;
readonly attribute DOMError? error;
[TreatNonCallableAsNull]
attribute EventHandler onsuccess;
[TreatNonCallableAsNull]
attribute EventHandler onerror;
};
error
of
type DOMError,
readonly , nullableerror
. Otherwise, it
MUST return the
value provided by by the error message. If there was
no provided value, it SHOULD return the most appropriate
DOMError that represents the
failure.
onerror
of type EventHandler,onsuccess
of type EventHandler,readyState
of type DOMString, readonlypending
if the
current state is pending
. Otherwise, it
MUST return
done
.result
of
type any,
readonlyundefined
if the
current state is not success
. Otherwise,
it MUST return
the value provided by the success message or
null
if no value was sent with the
message.
The following are the event handlers (and their corresponding
event handler event types) that
MUST be supported as
attributes by the DOMRequest
objects:
event handler | event handler event type |
---|---|
onerror |
error |
onsuccess |
success |
Thanks to the Samsung team, especially 金明(Ming Jin), Janusz Majnert and 송정기(Jungkee Song) for their work on the System Application Runtime: Execution and Security Model specification.
Special thanks to Anant Narayanan for his Web Application Manifest Format and Management APIs that this specification reuse shamlesly and to Jonas Sicking for being awesome, as always.