w3c / webappsec-csp

WebAppSec Content Security Policy
https://w3c.github.io/webappsec-csp/
Other
210 stars 78 forks source link

connect-src: wss without schema #429

Open axelssonHakan opened 4 years ago

axelssonHakan commented 4 years ago

Could someone share some light on an issue we are experiencing:

We aren't able to connect using WebSocket to an origin that isn't specified with a schema. Is it an issue or just how the source list syntax works?

Did some testing with a small webpage there I set the CSP as a meta tag and did a new WebSocket('wss://echo.websocket.org') in the dev. console

mikewest commented 4 years ago

The code you've written should be allowed by any of these policies. I'd suggest filing a bug against the browser in which this fails; if it's a bug in Chromium, I'd be happy to triage it. :)

annevk commented 4 years ago

If the enforcement happens in Fetch, the scheme would have been changed to http/https, right? Not sure that's accounted for.

axelssonHakan commented 4 years ago

Since I get the issue in "all" browsers I was wondering if we misunderstood something. Safari:

Screenshot 2020-03-20 at 15 21 59

Chrome:

Screenshot 2020-03-20 at 15 19 06

Firefox:

Screenshot 2020-03-20 at 15 18 36
bakkot commented 4 years ago

@mikewest I'm pretty sure the observed behavior of browsers is what the CSP spec says to do. If you intended it to work that's presumably a bug in the spec, which browsers have faithfully implemented.

Specifically,

If expression does not have a scheme-part, and origin’s scheme does not scheme-part match url’s scheme, return "Does Not Match".

Here indeed expression (echo.websocket.org) does not have a scheme-part. origin's scheme is presumably http or https. url's scheme is wss.

The scheme-part match algorithm is

two ASCII strings (A and B) are said to scheme-part match if the following algorithm returns "Matches":

  1. If one of the following is true, return "Matches":
    1. A is an ASCII case-insensitive match for B.
    2. A is an ASCII case-insensitive match for "http", and B is an ASCII case-insensitive match for "https".
    3. A is an ASCII case-insensitive match for "ws", and B is an ASCII case-insensitive match for "wss", "http", or "https".
    4. A is an ASCII case-insensitive match for "wss", and B is an ASCII case-insensitive match for "https".
  2. Return "Does Not Match".

You can verify for yourself that this returns "Does not match" when run on "https" and "wss".

Perhaps scheme-part match is being invoked with its arguments in the wrong order?

mikewest commented 4 years ago

As Anne noted above, https://fetch.spec.whatwg.org/#concept-websocket-establish flips wss to https (and ws to http) before eventually triggering the fetch in step 11, which then flows into the CSP checks you've pointed to.

Given that, we should be dealing with https://echo.websocket.org/ in the scheme-part match algorithm. I'm fairly certain that Chromium doesn't work the way Fetch expects, at least not at the point where we're performing this check. It's possible other browsers have made the same mistake.

mikewest commented 4 years ago

(Also, @bakkot: I really appreciate the thoroughness of your responses, here and on other bugs I've seen recently. Thank you!)

maxired commented 1 year ago

@axelssonHakan or @mikewest is there bug reported for differents browsers ?