WebSocket origin should have deterministic and validated origin header
Categories
(WebExtensions :: General, defect, P5)
Tracking
(Not tracked)
People
(Reporter: jamie, Unassigned)
References
(Blocks 1 open bug)
Details
(Whiteboard: triaged [sp3])
Comment 1•9 years ago
|
||
Updated•9 years ago
|
Reporter | ||
Comment 2•9 years ago
|
||
Comment 3•9 years ago
|
||
Comment 4•9 years ago
|
||
Updated•8 years ago
|
Comment 8•7 years ago
|
||
Reporter | ||
Comment 9•7 years ago
|
||
Comment 10•7 years ago
|
||
Comment 11•7 years ago
|
||
Comment 12•7 years ago
|
||
Comment 13•7 years ago
|
||
Comment 14•7 years ago
|
||
Reporter | ||
Comment 15•7 years ago
|
||
Comment 16•7 years ago
|
||
Updated•7 years ago
|
Updated•6 years ago
|
Comment 18•3 years ago
|
||
The "Origin" header with the deterministic UUID is matter for the server. It is like a signature, telling the server how trustworthy the client is.
I am talking about the server is owned by the extension developers, not the 3rd-party server, the browser should provides a mechanism to help the the extension developers to protect their server.
Currently in Chrome:
- if you install the extension from the Chrome Store, the UUID is deterministic, then the server will know the client is unmodified, is trust-able.
- If you install the extension with the Developer Mode, the UUID is random generated, then the server will know the client maybe modified, is not trust-able.
For example, the client has a restriction that request frequency is 1/min, a cracker and change this restriction to 1/sec in the extension code, and run the extension in the Developer Mode. But the server know the the client modified by the Origin header, so it can reject this client. Now the cracker need to crack the browser as well, he need to modify the browser source and compile it.
Cracking the extension JavaScript code more easier then compile the browser source, it only need to unzip the extension archive file, beautify the JavaScript code, find the restriction configuration keyword and change it. And the browser Store also doesn't allow obfuscate the code, so the extension code is more easier to read and debugged.
The deterministic UUID won't protect the server completely from a cracker, but at least it can prevent the modified client from being distributed to general users by the cracker, because general users also require a cracked browser binary file.
Please consider fix this bug, or make this behavior opt-in for the users.
Comment 19•3 years ago
|
||
(In reply to muzuiget from comment #18)
the browser should provides a mechanism to help the the extension developers to protect their server.
The browser is a User Agent, it acts on behalf of the user, not for the server developer. If the user decides to spoof a request to 3rd party software (e.g. by installing an alternative frontend for it) then they should be able to.
Updated•2 years ago
|
Updated•2 years ago
|
Comment 20•2 years ago
|
||
I'd like to +1 the suggestion in comment 4 to expose the WebExtension ID in the Origin
header. The current design makes it essentially impossible to use CORS to restrict access from unprivileged WebExtensions.
As I understand it, extensions are meant to be unprivileged by default unless they define permissions in their manifest. Thus, an extension with no permissions can be thought of as similar to a website on a random unprivileged origin.
CORS is meant to allow servers to define which origins they trust to share content with. That is why the requesting origin is included in the Origin
header, so that the backend can determine if the requesting origin should be allowed to access the resource. The issue here is that the Origin
header sent from web extensions is a random ID that does not allow this check to be done. So servers either have to:
- Allow requests from all extensions (which is akin to doing
Access-Control-Allow-Origin: *
) - Allow requests from no extensions (which is artificially limiting)
And I agree with comment 19 about the goal of a browser being a user agent. This is what host permissions enable: They make it possible for a user to purposefully grant an extension access to an origin without CORS restrictions. I agree that this is an important feature that should be preserved, but I think what we're discussing here is extensions that are meant to be unprivileged and thus fit into the wider web threat model.
Comment 21•2 years ago
•
|
||
(In reply to David Dworken from comment #20)
And I agree with comment 19 about the goal of a browser being a user agent. This is what host permissions enable: They make it possible for a user to purposefully grant an extension access to an origin without CORS restrictions. I agree that this is an important feature that should be preserved, but I think what we're discussing here is extensions that are meant to be unprivileged and thus fit into the wider web threat model.
Extensions are not really "unprivileged" with regards to the normal web security model. When granted access to all URLs they can completely bypass cors, they can access privileged headers. And they may eventually regain TCP/UDP socket access (legacy extensions used to have those).
Security restrictions on extensions are about protecting the user, not about protecting.
And extensions can have native components that can do about anything, including issuing arbitrary HTTP requests.
but I think what we're discussing here is extensions that are meant to be unprivileged and thus fit into the wider web threat model.
The issue is about the server trying to "validate" requests coming from specific extensions, i.e. locking services to specific client-side code. That's not the same as preventing unprivileged extensions from accessing sites they don't have permissions for.
Comment 22•2 years ago
|
||
Extensions are not really "unprivileged" with regards to the normal web security model. When granted access to all URLs they can completely bypass cors, they can access privileged headers. And they may eventually regain TCP/UDP socket access (legacy extensions used to have those).
I agree that when extensions have been granted host permissions, they become highly privileged. But when I say unprivileged I'm trying to refer to the default extension with no special permissions.
And extensions can have native components that can do about anything, including issuing arbitrary HTTP requests.
Though that requires the nativeMessaging
permission, so that isn't something they can do by default, right?
Security restrictions on extensions are about protecting the user, not about protecting.
I wholeheartedly agree. :) To me, the goal here is to make it possible for servers to protect user data from unprivileged extensions. This is what CORS enables (exposing a resource only to specific origins) and I believe is something that should also be possible with unprivileged extensions.
The issue is about the server trying to "validate" requests coming from specific extensions, i.e. locking services to specific client-side code. That's not the same as preventing unprivileged extensions from accessing sites they don't have permissions for.
I think the second piece is what I'd say the goal should be. Making it possible for a server to:
- Block unprivileged extensions from accessing sensitive resources
- Allow specific trusted extensions to access those resources
To me, this is akin to a server having a CORS policy that blocks all origins except *.example.com.
And in this scenario the user is still in full control: They can always grant an extension host permissions.
Comment 23•2 years ago
|
||
(In reply to David Dworken from comment #22)
Then host permissions already cover that? If the extension has an <all_urls>
permission then it can access everything. If it only has access to https://somedomain.org
then it can't access https://importantservice.com
. This is ensured on the client side. The server doesn't need to check anything.
Comment 24•2 years ago
|
||
(In reply to The 8472 from comment #23)
Then host permissions already cover that? If the extension has an
<all_urls>
permission then it can access everything. If it only has access tohttps://somedomain.org
then it can't accesshttps://importantservice.com
. This is ensured on the client side. The server doesn't need to check anything.
I don't believe this is true. If an extension only has host permissions to https://somedomain.org
, then it can still access other domains. It just can't do so in a way that bypasses standard web platform security features. To quote the docs, host permissions allow:
XMLHttpRequest and fetch access to those origins without cross-origin restrictions (even for requests made from content scripts)
So even without the permission, requests are allowed, they just have standard cross-origin restrictions applied to them.
Comment 25•2 years ago
|
||
(In reply to David Dworken from comment #24)
(In reply to The 8472 from comment #23)
Then host permissions already cover that? If the extension has an
<all_urls>
permission then it can access everything. If it only has access tohttps://somedomain.org
then it can't accesshttps://importantservice.com
. This is ensured on the client side. The server doesn't need to check anything.I don't believe this is true. If an extension only has host permissions to
https://somedomain.org
, then it can still access other domains. It just can't do so in a way that bypasses standard web platform security features. To quote the docs, host permissions allow:XMLHttpRequest and fetch access to those origins without cross-origin restrictions (even for requests made from content scripts)
So even without the permission, requests are allowed, they just have standard cross-origin restrictions applied to them.
Right, but those restrictions are considered sufficient under the web model. If the extension wants to talk to importantservice.com and actually see the response that can be accomplished by adding the host permission for importantservice.com.
Comment 26•2 years ago
|
||
(In reply to The 8472 from comment #25)
Right, but those restrictions are considered sufficient under the web model. If the extension wants to talk to importantservice.com and actually see the response that can be accomplished by adding the host permission for importantservice.com.
They're sufficient if the goal is to protect the user. But I don't think they're sufficient if the goal is to enable unprivileged extensions to be first class citizens of the web platform. As you said, right now the only way to allow an extension to talk to importantservice.com
is via a host permission. This gives the extension full access to importantservice.com
.
But suppose that this extension only needs to be able to call importantservice.com/api/endpoint
, an endpoint that is exposed via CORS to an enumerated set of origins.
- With the current model, the extension author must request the host permission which gives them a far wider set of permissions than they need. And this will make users less willing to install the extension since it is requesting such a privileged permission.
- With the model proposed in comment #4, the extension can be added to the CORS allowlist for just that endpoint. Thus the extension doesn't need to request a powerful scary host permission in order to be able to function.
At its core: the question is whether extensions should behave similarly to the web (and be able to use CORS in a meaningful way) or should they retain the current limited behavior.
Comment 27•2 years ago
|
||
(In reply to David Dworken from comment #26)
As you said, right now the only way to allow an extension to talk to importantservice.com is via a host permission. This gives the extension full access to importantservice.com.
But suppose that this extension only needs to be able to call importantservice.com/api/endpoint, an endpoint that is exposed via CORS to an enumerated set of origins.
Host permissions can be scoped to paths, they don't have to cover the full domain. And the permission is not really "scary", it primarily enables interacting with exactly the specified site, which the extension is intentionally going to do anyway. There shouldn't be an issue with making it explicit that the extension uses that API.
If the API is under the extension developer's control they can also choose to provide a separate host or endpoint just for extension access, to make it clear that it's ok to use that. Like importantservice.com/browserextensionaccess/.
At its core: the question is whether extensions should behave similarly to the web (and be able to use CORS in a meaningful way) or should they retain the current limited behavior.
The issue is that it would make extension requests identifiable. It could be abused both for vendor lock-in and to lock out extensions acting on behalf of the user. I'm sure there are some people who'd love to be able to block extensions just on the principle that it's not coming from "their authorized webpage".
Imo the browser should only send a null origin for CORS requests from an extension context if it doesn't have host permission, the host's origin if it does have host permission or the website's origin when doing it from a contentscript context
Updated•2 years ago
|
Updated•10 months ago
|
Description
•