1. Introduction
This section is non-normative.
Many User Agents prevent content from accessing non- same site data stored in cookies. This can break embedded content which relies on having access to non- same site cookies.
The
requestStorageAccessFor
API
enables
developers
to
request
access
to
non-
same
site
cookies
for
embedded
resources
such
as
iframes,
scripts,
or
images.
It
accomplishes
this
by
specifying
requestStorageAccessFor(requestedOrigin)
,
which
allows
traversable
navigable
s
to
request
access
to
unpartitioned
cookies
on
behalf
of
another
origin
.
2. Infrastructure
This specification depends on the Infra standard. [INFRA]
3. The requestStorageAccessFor API
This
specification
defines
a
method
that
can
be
used
to
request
access
to
unpartitioned
data
on
behalf
of
another
origin
(
requestStorageAccessFor(requestedOrigin)
).
Alex
visits
https://social.example/
.
The
page
sets
a
cookie.
This
cookie
has
been
set
in
a
first-party-site
context
.
Later
on,
Alex
visits
https://video.example/
,
which
has
an
img
in
it
which
loads
https://social.example/profile-image
.
In
this
case,
the
social.example
Document
doc
is
in
a
third
party
context
,
and
the
cookie
set
previously
might
or
might
not
be
visible
from
doc
.
cookie
,
depending
on
User
Agent
storage
access
policies.
A
script
on
https://video.example/
could
request
access
on
behalf
of
https://social.example
by
calling
doc
.
requestStorageAccessFor(requestedOrigin)
with
USVString
requestedOrigin
as
https://social.example
.
Note: the circumstances for use of the access have to be limited to those cases where the requested origin opts into sharing. More information is available in § 7 Privacy considerations and § 8 Security considerations .
Unpartitioned data is client-side storage that would be available to a site were it loaded in a first-party-site context .
A
Document
is
in
a
first-party-site
context
if
it
is
the
active
document
of
a
traversable
navigable
.
Otherwise,
it
is
in
a
first-party-site
context
if
it
is
an
active
document
and
the
origin
and
top-level
origin
of
its
relevant
settings
object
are
same
site
with
one
another.
A
Document
is
in
a
third
party
context
if
it
is
not
in
a
first-party-site
context
.
3.1.
Changes
to
Document
partial interface Document {Promise <undefined >requestStorageAccessFor (USVString ); };requestedOrigin
Document
doc
with
USVString
requestedOrigin
,
the
requestStorageAccessFor(requestedOrigin)
method
must
run
these
steps:
-
Let p be a new promise .
-
If doc is not fully active , then reject p with an "
InvalidStateError"DOMExceptionand return p . -
If doc ’s node navigable is not a traversable navigable , reject p with an "
NotAllowedError"DOMExceptionand return p . -
If doc ’s origin is an opaque origin , reject p with an "
NotAllowedError"DOMExceptionand return p . -
If doc ’s relevant global object is not a secure context , then reject p with a "
NotAllowedError"DOMExceptionand return p . -
Let parsedURL be the the result of running the URL parser on requestedOrigin .
-
If parsedURL is failure, reject p with a
TypeErrorand return p . -
Let origin be parsedURL ’s origin .
-
If origin is an opaque origin , reject p with an "
NotAllowedError"DOMExceptionand return p . -
If doc ’s origin is same origin with origin , resolve and return p .
-
Let descriptor be a newly created
TopLevelStorageAccessPermissionDescriptorwithnameset to "top-level-storage-access" and withrequestedOriginset to origin . -
Let has activation be true if doc ’s
Windowobject has transient activation , and false otherwise. -
Run these steps in parallel :
-
Let settings be doc ’s relevant settings object .
-
Let global be doc ’s relevant global object .
-
Let existing state be descriptor ’s permission state with settings .
-
If existing state is granted :
-
Queue a global task on the permissions task source given global to resolve p .
-
Return.
-
-
If existing state is denied :
-
If doc ’s
Windowobject has transient activation , consume user activation with it. -
Queue a global task on the permissions task source given global to reject p with a "
NotAllowedError"DOMException. -
Return.
-
-
Assert that doc ’s node navigable is a traversable navigable .
-
If has activation is false:
-
Queue a global task on the permissions task source given global to reject p with a n "
NotAllowedError"DOMException. -
Return.
-
-
Let permissionState be the result of requesting permission to use "
top-level-storage-access" with descriptor .NOTE: Note that when requesting permissions and deciding whether to show a prompt, user agents apply implementation-defined behavior to shape the end user experience. Particularly for
top-level-storage-access, user agents are known to apply custom rules that will grant or deny a permission without showing a prompt. -
If permissionState is granted :
-
Queue a global task on the permissions task source given global to resolve p .
-
Return.
-
-
If doc ’s
Windowobject has transient activation , consume user activation with it. -
Queue a global task on the permissions task source given global to reject p with a "
NotAllowedError"DOMException.
-
-
Return p .
The permissions task source shouldn’t be used directly. [privacycg/requestStorageAccessFor Issue #15]
3.2. User Agent top-level storage access policies
-
Let settings be request ’s client ’s relevant global object ’s relevant settings object .
-
Let descriptor be a newly created
TopLevelStorageAccessPermissionDescriptorwithnameset to "top-level-storage-access" and withrequestedOriginset to embedded origin . -
Let existing state be descriptor ’s permission state with settings .
-
If existing state is granted , return true.
-
Return false.
4. Permissions Integration
The
requestStorageAccessFor
API
defines
a
powerful
feature
identified
by
the
name
"
top-level-storage-access
".
It
defines
the
following
permission-related
algorithms:
-
PermissionDescriptor -
The
"
top-level-storage-access" powerful feature defines aPermissionDescriptoras follows:dictionary :TopLevelStorageAccessPermissionDescriptor PermissionDescriptor {USVString = ""; };requestedOrigin - permission query algorithm
-
To query the "
top-level-storage-access" permission, given aPermissionDescriptorpermissionDesc and aPermissionStatusstatus , run the following steps:-
Set status ’s
stateto permissionDesc ’s permission state . -
If status ’s
stateis denied , set status ’sstateto prompt .Note: The denied permission state is not revealed to avoid exposing the user’s decision to developers. This is done to prevent retaliation against the user and repeated prompting to the detriment of the user experience.
-
- permission key type
-
A
permission
key
of
the
"
top-level-storage-access" feature has the type site .Note: the
requestedOriginfield ensures that the permission store entry is double-keyed. - permission key generation algorithm
-
To generate a new permission key for the "
top-level-storage-access" feature, given anenvironment settings objectoriginsettingsorigin and origin embedded origin , run the following steps:-
Let current origin be settings ’ origin .Ifcurrentembedded origin is not same site withsettings ’ top-levelorigin,, return null. -
Return the result of obtaining a site from
settings ’ top-levelorigin..Note: the check for whether
settings ’embedded origin is same site withsettings ’ top-levelorigin is intended to disallow permission queries from cross-site frames. This depends on the invariant thattop-level-storage-accesspermission requests are only allowed in a top-level browsing context . As such, this check is only relevant inquery(permissionDesc).
-
- permission key comparison algorithm
-
To compare permission keys key1 and key2 for the "
top-level-storage-access" feature, run the following steps:-
If key1 is null or key2 is null, return false.
-
Return key1 is same site with key2 .
-
5. Fetch Integration
The
requestStorageAccessFor(requestedOrigin)
only
directly
affects
cookie
behavior
on
subresource
requests
made
from
top-level
documents
to
the
requested
origin
.
-
Let has top-level access be the result of running determine if a request has top-level storage access on request .
-
If has top-level access is false, return false.
-
Let is subresource be true if request is a subresource request and false otherwise.
-
Let allowed subresource mode be true if request ’s mode is "cors" and request ’s credentials mode is "include", and false otherwise.
-
If is subresource is true and allowed subresource mode is false, return false.
-
If request ’s client ’s relevant global object ’s associated document is not a traversable navigable , return false.
-
Return true.
6. Storage Access API Integration
Note:
even
after
a
successful
requestStorageAccessFor(requestedOrigin)
call,
frames
have
to
explicitly
invoke
requestStorageAccess()
for
cookie
access.
This
modification
allows
requestStorageAccessFor(requestedOrigin)
to
allow
resolution
of
requestStorageAccess()
calls
similarly
to
a
prior
successful
requestStorageAccess()
grant.
requestStorageAccess()
to
insert
the
following
steps
before
step
13.4
(i.e.
before
checking
transient
activation):
-
Let settings be doc ’s relevant settings object .
-
Let origin be settings ’ origin .
-
Let descriptor be a newly created
TopLevelStorageAccessPermissionDescriptorwithnameset to "top-level-storage-access" and withrequestedOriginset to origin . -
If descriptor ’s permission state is granted , queue a global task on the permissions task source given global to resolve p , and return.
-
If descriptor ’s permission state is denied , queue a global task on the permissions task source given global to reject p with a "
NotAllowedError"DOMException, and return.
7. Privacy considerations
Like
the
[STORAGE-ACCESS]
,
requestStorageAccessFor(requestedOrigin)
is
intended
to
enable
removal
of
cross-site
cookies.
It
enables
developers
to
re-gain
cross-site
cookies
with
additional
constraints.
Note: many of the same considerations as in The Storage Access API § 6 Privacy considerations apply. This section primarily covers the differences.
requestStorageAccess()
requires
interaction
with
an
embedded
document.
By
requiring
interaction
only
with
the
top-level
document,
requestStorageAccessFor(requestedOrigin)
lowers
the
bar
for
a
potential
prompt,
though
embedded
documents
can
also
be
quite
prominent
(or
use
other
techniques
to
get
user
interaction).
Implementation-defined
acceptance
and
rejection
steps
are
intended
to
allow
user
agents
to
reject
abusive
requests
based
on
logic
they
see
fit.
The
prompts
used
have
to
be
careful
to
indicate
the
direction
of
the
request,
such
that
the
user
is
able
to
understand
who
is
requesting
access.
As
with
requestStorageAccess()
,
the
same
tension
between
user
consent
and
prompt
fatigue
exists
with
requestStorageAccessFor(requestedOrigin)
;
much
like
the
Storage
Access
API,
implementation-defined
acceptance
and
rejection
steps
are
intended
to
enable
implementers
with
differing
stances
on
this
question
to
make
compromises
as
they
see
fit.
Another difference is that queries for the permission can be more sensitive, depending on the context. Note that a frame has to be unable to request the state of either of:
-
Whether it was granted a "
top-level-storage-access" permission for some origin while a top-level document. -
Whether arbitrary other origins were granted the "
top-level-storage-access" on the current top-level site.
In the former case, this would allow bogus domains (or combinations thereof) to be used as identifiers; in the latter case, it would reveal state under unrelated origins.
8. Security considerations
It
is
important
that
requestStorageAccessFor(requestedOrigin)
not
degrade
security
properties
of
the
web
platform,
even
when
compared
to
post-removal
of
cross-site
cookies.
Third-party
cookie
removal
has
potential
benefits
for
security
,
specifically
in
mitigating
attacks
that
rely
upon
authenticated
requests,
e.g.
CSRF.
We
do
not
wish
requestStorageAccessFor(requestedOrigin)
to
be
a
foothold
for
such
attacks
to
leverage.
Note:
The
Storage
Access
API
§ 7
Security
considerations
properties
hold
for
much
of
this
proposal.
Specifically,
frame-level
access
is
only
granted
once
requestStorageAccess()
is
successfully
invoked.
For
frame
access,
requestStorageAccessFor(requestedOrigin)
merely
simplifies
the
activation
and
prompting
requirements.
requestStorageAccessFor(requestedOrigin)
does
expand
the
scope
of
concerns
in
two
areas:
subresource
requests
made
by
the
top-level
document
and
potential
notification
abuse.
8.1. Subresource Requests
The specific security controls proposed by the API are:
-
Any cookies included with the subresource request have to be explicitly marked
SameSite=None, indicating intent for use in third party contexts . -
For any
SameSite=Nonecookies to be included, the request’s mode has to be "cors", where reading of the response is blocked unless the embeddee opts-in via sending the appropriate `access-control-allow-credentials` header. The sending of the `origin` header ensures the embeddee is aware of the embedder’s identity.
Additionally,
only
requests
initiated
from
the
top-level
document
will
be
eligible
for
inclusion
of
SameSite=None
cookies.
This
ensures
that
other
embedded
frames
do
not
receive
escalated
privileges.
8.2. Notification Abuse
Unlike the [STORAGE-ACCESS] , interaction is only required with the top-level document, rather than an embedded document. This does increase the likelihood of prompting.
Like the Storage Access API, user activation is consumed on denial, which prevents repeated requests.
The implementation-defined rejection steps also allow for imposition of numeric limits or denylists for abusive actors.
As mentioned in § 7 Privacy considerations , because of the direction of the request, the language in user agents' prompts should indicate which site initiated the storage access request.