Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CORS section #13

Merged
merged 15 commits into from
Aug 29, 2019
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion main/introduction.bs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ Issue: Explain that this specification is not documentation;

## Definitions ## {#definitions}

Issue: Write Definitions section.
A <dfn export>data pod</dfn> is a place for storing documents,
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
with mechanisms for controlling who can access what.

A <dfn export>Solid app</dfn> is an application
that reads or writes data from one or more [=data pods=].
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved

Issue: Introduce the structure of this document.
[Cross-server interoperability](#resource-access)
Expand Down
102 changes: 98 additions & 4 deletions main/resource-access.bs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,101 @@ A Solid data pod MUST conform to the Web Access Control specification [[!WAC]].

## Cross-Origin Resource Sharing ## {#cors}

Issue: Write Cross-Origin Resource Sharing section.

Draft:
A Solid data pod MUST conform to the CORS specification [[!FETCH]].
### Background and Need ### {#cors-need}
<em>This section is non-normative.</em>

[=Solid apps=] typically access data from multiple sources.
However,
Web browsers by default prevent apps that run on one origin
from accessing data on other origins.
This cross-origin protection is a security mechanism
that ensures malicious websites cannot simply read
your profile or banking details from other websites.
However, this reasonable default poses a problem
even for benevolent Solid apps,
which might have good reasons to access data from different places.
For instance,
a Solid app at `https://app.example/`
would be prevented from accessing data on
`https://alice-data-pod.example/` or `https://bob-data-pod.example/`,
even when Alice and Bob have given the user of the app
their permission to see some of their data.

For cases where the other origins
have their own access protection mechanism—
[like within Solid](#wac)—
the browser's built-in cross-origin protection
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
is actually an obstacle rather than a feature.
After all,
[=data pods=] already ensure through access control
that certain documents can only be accessed
by specific people or applications.
Preventively blocking apps from different origins
thus introduces an unnecessary barrier.

Fortunately,
Web servers can indicate to the browser
that certain documents do not require cross-origin protection.
This mechanism to selectively disable that protection
is called *Cross-Origin Resource Sharing* or *CORS* [[FETCH]].
By responding to browser requests
with a specific combination of HTTP headers,
servers can indicate which actions are allowed for a given resource.
For a Solid data pod,
the goal is to allow *all* actions on the CORS level,
such that the deeper [access control layer](#wac)
can exert full control over the app's allowed permissions.
The next section describes how to achieve this
through the right HTTP header configuration.


### Required server-side implementation ### {#cors-server}

A [=data pod=] MUST implement the CORS protocol [[!FETCH]]
such that, to the extent possible,
the browser allows Solid apps
to send any request and combination of request headers
to the data pod,
and the Solid app can read any response and response headers
received from the data pod.
If the data pod wishes to block access to a resource,
this MUST NOT happen via CORS
but MUST instead be communicated to the Solid app in the browser
through HTTP status codes such as
`401`, `403`, or `404` [[!RFC7231]].

Note: Since the CORS protocol is part of a Living Standard,
it should still be considered in evolution.
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
Changes to the CORS protocol might thus happen at any point,
which might necessitate changes to server implementations
for continued prevention of undesired blocking.
A [proposal](https://github.com/whatwg/fetch/issues/878) to mitigate this
has been suggested.

RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
Concretely,
whenever a data pod receives an HTTP request
containing a valid `Origin` header [[!RFC6454]],
the server MUST respond with the appropriate `Access-Control-*` headers
as specified in the CORS protocol [[!FETCH]].
In particular,
the data pod MUST set the `Access-Control-Allow-Origin` header
to the valid `Origin` value from the request
and list `Origin` in the `Vary` header value.
The data pod MUST make all used response headers readable for the Solid app
through `Access-Control-Expose-Headers`
(with the possible exception of the `Access-Control-*` headers themselves).
A data pod MUST also support the HTTP `OPTIONS` method [[!RFC7231]]
such that it can respond appropriately to CORS preflight requests.
csarven marked this conversation as resolved.
Show resolved Hide resolved

Careful attention is warranted,
especially because of the many edge cases.
For instance,
data pods SHOULD explicitly enumerate
all used response headers under `Access-Control-Expose-Headers`
rather than resorting to `*`,
which does not cover all cases (such as credentials mode set to `include`).
Data pods SHOULD also explicitly list `Accept` under `Access-Control-Allow-Headers`,
because values longer than 128 characters
(not uncommon for RDF-based Solid apps)
would otherwise be blocked,
despite shorter `Accept` headers being allowed without explicit mention.
43 changes: 42 additions & 1 deletion main/security.bs
Original file line number Diff line number Diff line change
@@ -1,7 +1,45 @@
Security Considerations {#security}
===================================

Issue: Write Security Considerations section.
A data pod MUST NOT assume that
HTTP request headers sent by a client are valid,
and MUST reject or sanitize invalid header values
before processing them
or incorporating them in messages sent to others.
For example,
values for `Host` and `Origin`
MUST NOT be assumed to be free of possibly malicious sequences
such as `/..` or others,
and invalid `Origin` values
MUST NOT be echoed into the `Access-Control-Allow-Origin` response header.

A data pod MUST NOT assume that the user agent is a regular Web browser,
even when requests contain familiar values
in headers such as `User-Agent` or `Origin`.
Such an assumption could lead to incorrect conclusions
about the security model of the application making the request,
since the request might actually come
from a non-browser actor unaffected by browser security constraints.

Solid data pods [disable all cross-origin protections](#cors-server) in browsers
because resource access is governed explicitly by [Web Access Control](#wac).
As such,
data pods MUST NOT rely on cross-origin protection
for shielding access to resources.
While this ensures that unauthorized resource access will not occur,
additional security measures MAY be taken
to prevent metadata in error responses from leaking.
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
For instance,
a malicious app could probe multiple servers
to check whether the response status code is `401` or `403`,
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
or could try to access an error page
from an intranet server within the user agent's private network
to extract company names or other data.
To mitigate this,
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
when a request from an untrusted `Origin` arrives,
the data pod MAY set the status code of error responses to `404`
dmitrizagidulin marked this conversation as resolved.
Show resolved Hide resolved
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved
and/or anonymize or censor their contents.


## Privacy Considerations ## {#privacy}

Expand All @@ -10,3 +48,6 @@ Issue: Write Privacy Considerations section.
### Identifiable Information ### {#identifiable-information}

Issue: Write Identifiable Information section.

In order to prevent leakage of non-resource data,
error responses SHOULD NOT contain identifiable information.
RubenVerborgh marked this conversation as resolved.
Show resolved Hide resolved