-
Notifications
You must be signed in to change notification settings - Fork 350
Add usage advice for Sec- #1818
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,11 +22,15 @@ urlPrefix:https://httpwg.org/specs/rfc9651.html#;type:dfn;spec:rfc9651 | |
url:;text:structured header | ||
url:token;text:structured field token | ||
|
||
urlPrefix:https://httpwg.org/specs/rfc9110.html#;type:dfn;spec:http | ||
url:method.overview;text:method | ||
url:fields.names;text:field-name | ||
url:fields.values;text:field-value | ||
url:rfc.section.9.2.1;text:unsafe | ||
urlPrefix:https://httpwg.org/specs/rfc9110.html#;spec:http | ||
type:dfn | ||
url:method.overview;text:method | ||
url:fields.names;text:field-name | ||
url:fields.values;text:field-value | ||
url:rfc.section.9.2.1;text:unsafe | ||
type:http-header | ||
url:field.connection;text:Connection | ||
url:field.upgrade;text:Upgrade | ||
|
||
urlPrefix:https://httpwg.org/specs/rfc9111.html#;type:dfn;spec:http-caching | ||
url:delta-seconds;text:delta-seconds | ||
|
@@ -41,6 +45,10 @@ urlPrefix:https://httpwg.org/specs/rfc9111.html#;type:dfn;spec:http-caching | |
urlPrefix:https://httpwg.org/specs/rfc9112.html#;type:dfn;spec:http1 | ||
url:status.line;text:reason-phrase | ||
|
||
url:https://datatracker.ietf.org/doc/html/rfc6455;type:http-header;spec:websocketprotocol | ||
text:Sec-WebSocket-Accept | ||
text:Sec-WebSocket-Key | ||
|
||
url:https://w3c.github.io/resource-timing/#dfn-mark-resource-timing;text:mark resource timing;type:dfn;spec:resource-timing | ||
|
||
urlPrefix:https://w3c.github.io/hr-time/#;spec:hr-time | ||
|
@@ -9062,6 +9070,88 @@ done only by navigations). The <a>fetch controller</a> is also used to | |
<a for=request>redirect mode</a> set to "<code>manual</code>". | ||
|
||
|
||
<h3 id=sec-advice>Defining fields with a `<code>Sec-</code>` prefix</h3> | ||
|
||
<p>Fetch defines a set of <a>forbidden request-headers</a> and the `<code>Sec-</code>` prefix for | ||
<a for=/>headers</a> that are intended to be exclusively generated by the user agent. Callers of | ||
<a>fetch</a> cannot set these values when making requests. | ||
|
||
<p>This prohibition provides servers some assurance that a <em>browser</em> produced these | ||
<a for=/>headers</a>. However, this assurance is limited to request that could only have been | ||
generated by an honest user agent. Other types of application–including malicious browsers–can | ||
provide any value for any <a>header</a>. | ||
|
||
<p><a>Forbidden request-headers</a> are most useful where servers need to make security | ||
decisions about the value of those <a for=/>headers</a> on <a for=/>requests</a> that also include | ||
<a for=/>credentials</a>. | ||
|
||
<p>Whether the value of <a>forbidden request-headers</a> can be trusted to be accurate then depends | ||
on a judgment about the trustworthiness of the entity that is presenting | ||
<a for=/>credentials</a>. Any client or user agent acting on behalf of a malicious user might | ||
present falsified information if that serves the user's interests. | ||
|
||
|
||
<h4 id=sec-reasons>Reasons to use a `<code>Sec-</code>` prefix</h4> | ||
|
||
<p>It is not enough that a value originates from a user agent to justify the use of | ||
`<code>Sec-</code>`, a server needs to depend on the accuracy of the information in the | ||
<a>header</a>. When deciding whether to add a new <a>header</a> to the set of <a>forbidden | ||
request-headers</a> by adding a `<code>Sec-</code>` prefix to its name, consider first whether a | ||
server might make a security decision that relies on an accurate <a>header</a> value. | ||
|
||
<p id=sec-connection class=example>A [:Connection:] <a>header</a> with a value of | ||
`<code>close</code>` causes the server to close a connection after producing a | ||
<a for=/>response</a>. This is not a capability that <a>fetch</a> is intended to enable, making this | ||
a natural choice for a <a>forbidden request-header</a>. | ||
|
||
<p id=sec-ws-key class=example>The [:Sec-WebSocket-Key:] <a>header</a> is used on a | ||
`<code>GET</code>` <a for=/>request</a> made during the WebSocket handshake. Using the | ||
`<code>Sec-</code>` prefix for [:Sec-WebSocket-Key:] ensures that a server that does not check other | ||
<a for=/>headers</a> (such as [:Upgrade:]) cannot be duped into | ||
believing that a <a>fetch</a> is a WebSocket connection attempt. | ||
|
||
<p>Routine security checks can be aided as a result of having more accurate information, even if | ||
there are cases where information might be spoofed by a malicious client. | ||
|
||
<p id=why-sec-fetch-dest-is-sec class=example>The [:Sec-Fetch-Dest:] <a>header</a> might be used in | ||
<a for=/>requests</a> both with or without <a for=/>credentials</a>. The decisions that a server makes using | ||
[:Sec-Fetch-Dest:] can be security-relevant for an honest user agent, even for <a for=/>requests</a> | ||
without credentials. | ||
|
||
|
||
<h4 id=sec-not-ok>Reasons not to use a `<code>Sec-</code>` prefix</h4> | ||
|
||
<p>That a <a>header</a> value might be needed to answer a <a>CORS-preflight request</a> is | ||
<em>not</em> a sufficient reason to use a `<code>Sec-</code>` prefix; all <a>CORS-preflight | ||
requests</a> include [:Access-Control-Request-Method:], which is [=forbidden | ||
request-headers|forbidden=]. Any <a for=/>headers</a> that a fetch caller sets will not be set on a | ||
<a>CORS-preflight request</a> made by an honest user agent; instead, these are listed in | ||
[:Access-Control-Request-Headers:]. | ||
|
||
<p id=sec-purpose-no-sec class=example>The [:Sec-Purpose:] field tells a server that a | ||
<a for=/>request</a> is speculative. A server might choose to avoid triggering side-effects while | ||
processing such a request, such as suppressing the recording of page view metrics. Making this a | ||
<a>forbidden request-header</a> has no security-relevant purpose and the `<code>Sec-</code>` prefix | ||
is therefore unnecessary. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a redefinition of the threat model. See w3c/resource-hints#74 (comment) for a discussion of this header. Sending new headers across origin without preflight and without a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I traced the origin of Sec-Purpose to that thread. You do not establish a reason for it being forbidden, but instead assume that to be the case. If there was a risk that a server might be confused by the presence of the field, that would have been obvious. That case was not made, only asserted without evidence. Sending new headers has to be safe in HTTP. We routinely add new headers in the IETF and have not encountered significant problems from having done so. Obviously, there is always a risk of collision, but we have things like the HTTP archive to aid in identifying potential conflicts. The point about preflight is only relevant if there is a) a conflict, b) a security-relevant decision being made that relies on the values being correct, and c) a resource that has harmful side effects on requests that are not already subject to preflight. That's a pretty tight set of conditions. I can make a clear case for Sec-Fetch-Dest as it pertains to JSONP (perhaps) and maybe some forms of script inclusion.. That clearly justifies the use of a prefix. |
||
|
||
<p class=note>There are a number of <a for=/>headers</a> that use the `<code>Sec-</code>` prefix for | ||
legacy reasons. Consistency with these existing <a for=/>headers</a> is not a reason to use the | ||
`<code>Sec-</code>` prefix for new <a for=/>headers</a>. | ||
|
||
<p id=sec-ch-no-sec class=example><a href=https://datatracker.ietf.org/doc/html/rfc8942>Client | ||
hints</a> give a server the ability to adapt content. Making these <a>forbidden request-headers</a> | ||
denies fetch callers the ability to access this adaptation capability unnecessarily. | ||
|
||
<p>The `<code>Sec-</code>` prefix has no purpose for <a for=/>headers</a> that are exclusively used | ||
for <a for=/>responses</a>. Only consider the application of the `<code>Sec-</code>` prefix <a | ||
for=/>headers</a> that are used in <a for=/>requests</a>. | ||
|
||
<p id=ws-sec-prefix class=example>The [:Sec-WebSocket-Accept:] <a>header</a> is a | ||
<a for=/>response</a> <a>header</a> that is exclusively used for the | ||
<a href=https://datatracker.ietf.org/doc/html/rfc6455#section-4>WebSocket handshake</a>. This | ||
<a>header</a> has no need to use the `<code>Sec-</code>` prefix. | ||
|
||
|
||
<h2 id=acknowledgments class=no-num>Acknowledgments</h2> | ||
|
||
<p>Thanks to | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is a compelling example as these were introduced prior to the introduction of the prefix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree. It's quite a compelling example in that it is forbidden for a very good reason. (I don't know why you quoted the unrelated text about ACRH, is there a point you wanted to make there?