dbsc icon indicating copy to clipboard operation
dbsc copied to clipboard

`Sec-` prefix for a server header

Open yoavweiss opened this issue 1 year ago • 5 comments

AFAIK, the purpose of the Sec- prefixed header is to provide some guarantees about browser-provided headers and prevent JS code from altering/overriding them. I don't think any of that applies to server provided headers. Is there any reason for the prefix?

yoavweiss avatar Jun 10 '24 08:06 yoavweiss

@arnar Suggested this.

Headers go both way here, so there are are headers sent were we want this kind of protection. We also want this protection for response headers to make sure JS cannot alter them to protect from among others reply attacks.

kmonsen avatar Jun 12 '24 18:06 kmonsen

Headers go both way here, so there are are headers sent were we want this kind of protection.

That makes sense for the request headers, but I'm not convinced that the response headers should mirror that prefix.

We also want this protection for response headers to make sure JS cannot alter them to protect from among others reply attacks.

I don't think Sec- gives you that protection.

yoavweiss avatar Jun 13 '24 04:06 yoavweiss

https://datatracker.ietf.org/doc/html/rfc8942#:~:text=the%20Sec%2D%20prefix,%C2%B6

the Sec- prefix on the header field name has the effect of preventing scripts and other application content from setting them in user agents. Using the "Sec-" prefix signals to servers that the user agent -- and not application content -- generated the values. See [FETCH] for more information.

theMiddleBlue avatar Jul 23 '24 05:07 theMiddleBlue

That's true for request headers but not for response headers.

yoavweiss avatar Jul 23 '24 15:07 yoavweiss

The Fetch spec indeed only uses "sec-" to mark headers as forbidden request headers, and the only forbidden response headers are Set-Cookie and Set-Cookie2.

Forbidden response headers are filtered from JS to see them, based on a set of rules that e.g. include taking CORS into account.

So @yoavweiss is correct in that "Sec-" does not do anything automatically for response headers, but the takeaway is whether we should think about if any of the response headers we are defined ought to be forbidden headers (e.g. hidden from XHR responses).

arnar avatar Jul 23 '24 19:07 arnar

Any progress on this?

I agree with OP that using Sec- for response headers is wrong. Presumably since these are new requests CORS is used and therefore the server could only expose these headers using Access-Control-Expose-Headers. I don't think we need a new mechanism that protects headers from being revealed even when included therein, but I guess I'm willing to be convinced. (If you manage to convince me though, Sec- seems like an inappropriate mechanism still as Sec- does not imply the header is not exposed. They sometimes are to service workers and such. It just means the header cannot be controlled.)

annevk avatar Nov 20 '24 18:11 annevk

I have no strong opinion here, we put it in originally from a misunderstanding I think has been corrected in this discussion.

@kristianmonsen I'm fine dropping "Sec-" from the response headers.

arnar avatar Nov 20 '24 20:11 arnar

I can change that, it's a bit of work so just checking here first if we agree on what would be better. My proposal is:

  • All request headers stay as they are, so for example Sec-Session-Id and Sec-Session-Response. I'll try to think of a new name for Sec-Session-Response as it is a bit confusing.
  • For all response headers, I'll change them from Sec-Session-* to Secure-Session-*, so for example Sec-Session-Registration becomes Secure-Session-Registration

Would this work?

kmonsen avatar Nov 27 '24 20:11 kmonsen

The prefix "Sec-" was really serving two purposes, so that our headers aren't just "Session-..." -- since that term in isolation is already heavily overloaded.

I know it sounds silly but I think we should have a common prefix for all the headers defined by this spec, and since "Sec-Session-" doesn't work, the next best option is "Secure-Session-" everywhere. That means the request headers would be "Sec-Secure-Session-..." 🙄

But silly as it is, that's IMO better than sometimes using "Secure-Session-" and other times "Sec-Session-". And it assigns no additional meaning to "Sec-", which is what I understand this issue to be about.

arnar avatar Nov 27 '24 22:11 arnar

So:

  • Request: Sec-Secure-Session-*
  • Response: Secure-Session-* ?

My preference would be to make them all Secure-Session-*, I am not sure if Sec- on request headers really changes anything practically for DBSC..

kmonsen avatar Nov 27 '24 22:11 kmonsen

I think if it's exactly the same header using the same name is reasonable.

Where in the Fetch processing model do these get set? What if a web developer has already set them? The former is important regardless, the latter is important if you don't use Sec-.

annevk avatar Nov 28 '24 07:11 annevk

I'm not seeing any symmetry here, nor a reason to use Sec- on the requests. Though the spec is pretty scant on details about session establishment, which is where the biggest risks lie.

If the key that is used is genuinely held by a user agent, there is no need to use Sec- on any request that contains proof of knowledge for the privacy key (i.e., a signature). The field itself carries proof.

The risk comes from the registration process. If an attacker could intercept that, then they create a persistent impersonation vector. That probably requires ongoing interception of use of the key from that point onward, but the whole point of this is access to the key is the thing providing protection. (And if you are signing over HTTP-only cookies, that's a tall order for a compromised web app.)

The main security risk I see is the registration process. That is not something that you can protect with Sec-. I would argue that you can't really protect that step anyway, so maybe that is better off moved to a less awkward API surface.

martinthomson avatar Mar 31 '25 06:03 martinthomson

Our CORS integration is still somewhat up in the air (I've just updated https://github.com/w3c/webappsec-dbsc/issues/81 with my thoughts), so this is all with a grain of salt, but I do think there's some value in the Sec- headers on requests so that endpoint can get a little validation about refreshes being real refreshes and not an XHR. CORS helps here of course, but the cost of keeping Sec- on the requests is low, so the added benefit seems nice.

Our current spec says that refresh requests are HTTP-network-or-cache fetches, so we inject the header there. I'm not certain that's correct though, if you have a different opinion.

drubery avatar Apr 01 '25 20:04 drubery

Is this Secure- header going to be defined as a special header in HTTP and Fetch? Or is it only in this specification? If the latter, shouldn't it be a prefix related to the specification name, like DBSC-, instead of the meaningfully named Secure-?

Jxck avatar May 16 '25 05:05 Jxck

We shouldn't name headers based on the specification they are defined in. "Don't ship the org chart."

annevk avatar May 16 '25 06:05 annevk

OK, in that case, what makes the Secure- prefix appropriate here ?Sec- is defined as "It's not injected by JavaScript", but Secure- doesn't guarantee that something is "Secure". if just Session-Registration and so has potential compatibility issues.And Secure- just covers that, it means it's just the same as X-. Which is not recommended based on experience of http.

Jxck avatar May 16 '25 06:05 Jxck

That's a fair question and I'd recommend opening a new issue for it (referencing this one) as closed issues aren't always tracked all that well.

annevk avatar May 16 '25 07:05 annevk

"Secure-" isn't meant as a prefix here with some meaning, but rather "Secure-Session-" as the prefix for headers related to this spec. Just "Session-" feels not specific enough.

arnar avatar May 16 '25 18:05 arnar