-
Notifications
You must be signed in to change notification settings - Fork 54
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
Please require a secure origin (Bug 25972) #28
Comments
Add text saying "Developers should use Secure Origins, although this is not strictly required." |
Discussion on 7/11 call suggest requiring a secure origin, in the stronger sense of requiring the top-level browsing context to be secure. |
I assume that the secure origin test should be performed as the first step in each WebCrypto method. This would mean that errors due to WebIDL type conversion would still occur on insecure origins, but then you would get the secure origin test failure. IIUC, Chrome's current implementation does algorithm normalization and possibly other parameter validation before checking for the secure origin. |
PR #122 |
-1 for requiring a secure origin (though I'm okay with it being recommended). The "Secure Messaging" use case, for example, doesn't require TLS in order to preserve the privacy of the exchange, so long as only ciphertext is transmitted. Simply put, we don't want the extra roundtrips associated with establishing a TLS session when they are superfluous to the actual security solution, since this leads to a worse end-user experience with no tangible benefit. |
Whatever you do, please do not use the incumbent or entry settings objects here. Current settings object is more correct. See https://readable-email.org/list/public-script-coord/topic/multiple-globals-and-you |
Looking at https://w3c.github.io/webappsec-secure-contexts/#new, would it be simpler to add |
That would probably work, although it would have different normative effects than adding a guard. (Adding a guard causes errors at call time, whereas [SecureContext] prevents the interfaces from existing at all.) |
@bdhess Without a secure origin, you can only make security arguments with respect to passive attackers. An active attacker - one who can modify the pages served to the client - has full access. Privacy against passive observation is not without value and this is the argument I have used in the past against requiring a secure origin. However, we'd need some evidence that there were users with that use-case as a requirement (my company was one of those, but no longer). |
@mwatson2 In our operating environment, there's no sensitive data or PII that's emanating from the client. Ultimately, our use of Web Crypto is entirely to provide security around server-provided assets. So the protection of client-side key material is therefore a concern for us, but as I understand it, out of scope for Web Crypto. |
Adding the |
w3c/webcrypto#28 noted that the current recommendations were confusing as they suggested both throwing and hiding the interface. This patch clarifies that either/or is completely acceptable.
Is it web-compatible to hide the API from insecure contexts? That's the main tradeoff solution-wise. |
Safari and IE both ship prefixed variants of the |
Marking with [SecureContext] SGTM.
Note that Chrome already doesn't allow Web Crypto over non-secure origins. So clients needing to support Chrome will have to address this in their implementation regardless.
Chrome (currently) does the origin check after (most) WebIDL checks on the parameters, but before things like "algorithm normalization", and rejects with NotSupportedError in that case. Hence it is not very consistent as far as what parameters have been processed. Marking with [SecureContext] avoids that problem. What should happen when structured (de) cloning a CryptoKey into an insecure context? Under the crypto.subtle is hidden model, I presume you could still postMessage a CryptoKey to an insecure context. Is that relevant? |
So the contention is, since Chrome has already defined a behavior, there's no point in discussing changes that would make the spec inconsistent with Chrome's present behavior? This seems like a really backwards way of developing community standards. I'm not the first person to object to this behavior: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25972#c6 From the record, it's pretty clear that Chrome came to this decision based on the assumption that there exists no scenario in which there is value in being able to use the Web Crypto API in an insecure context. Including myself, there are at least four commenters who've disputed that. |
I suspect that were you to ask the people that objected to this in the past again, they are probably more agreeable to this now. E.g., Mark commented in this very thread saying so. Also, the concerns Ehsan raised there were mostly about the original solution easily being bypassed. Secure contexts addresses those concerns. He didn't really state any use cases for Web Crypto in insecure contexts and I don't really think you have clearly done so either. |
New PR using |
A problem with PR #131 is that it marks window.crypto as [SecureContext]. This means that window.crypto.getRandomValues() is no longer accessible on insecure contexts. I don't believe we want that change -- getRandomValues() has always been available on insecure contexts. Instead I propose marking only SubtleCrypto (i.e. window.crypto.subtle) as [SecureContext]. |
@varunnaagaraj This sounds like a webkit-specific question or issue, so I would start there. In any case, it's off-topic for this thread. |
(Not totally off topic, IMHO, since Webkit is the new W3C, as far as I'm observing it). Anyway, @varunnaagaraj you are doomed to find another solution without webcrypto as this issue points out, there is no webcrypto on http. And there is no https for localhost, so no webcrypto for you. |
@X-Ryl669 localhost is in fact considered a potentially secure origin, see https://w3c.github.io/webappsec-secure-contexts/. I believe Web Crypto works on localhost in most browsers. |
Well sorry, my mistake. I meant local host on your LAN (not 127.0.0.1 or ::1). |
I've been monitoring this thread for a long time... I feel like a happy compromise that could resolve many of the complaints in this thread satisfactorily would be to white-list class A, B, C private subnets to use this module (e.g. if you are developing on a VM or other computer on the same LAN network). So allow crypto on local networks like |
@pztrick you can’t make assumptions about how routers are configured. Even given that the 192.168.255.255/16 range is reserved by (ICANN? ARIN? I forget which entities control what) - a compromised router may deliver traffic destined to these addresses to any server on the web. |
I did say compromise and not perfection. :)
My understanding, and correct me if I'm wrong, for removing the crypto API on non-secure hosts is for developers to catch this footgun if for example they develop on On the other hand, if your hostname is accessed over HTTP without HSTS any usage of |
@varunnaagaraj Sorry, I'm not sure I understand your question. There's nothing a polyfill or script can do to change whether a context is considered to be secure/trustworthy, no. |
Well what I meant was, PolyfillCrypto basically creates a Proxy reference to all the subtlecrypto api's. Im guessing if this WindowProxy is the reason for the session being termed insecure. |
The two things are unrelated. A Web Crypto polyfill can provide fallback implementations of crypto operations, but it can't access the native implementation of Web Crypto if the context is insecure. The context being insecure because of an insecure opener that holds a reference via a WindowProxy, can be fixed as is explained further down in the example you saw. |
The doctrine you refer to ends: "Of course, it is preferred to make things better for multiple constituencies at once." Let's check on all named constituents:
To follow the priority of constituencies would be to help all but one group at once by not requiring secure origin. |
Of course, if it was possible to make both users and authors happy, then we should do that. But that's why the first sentence applies: there's a conflict here, and users are more important than authors (and everything else on the list). It doesn't say that authors + implementors + specifiers + theoretical purity outweigh users. And anyway I don't agree with the last three crosses on that list. IMO more accurate would be:
The web in general is moving to being HTTPS-only. It's even easier and cheaper today to request a TLS certificate for any website than it was in 2016, thanks to initiatives like Let's Encrypt. For local applications, something like Electron can be used. For IoT devices, rather than hosting the entire web app on the device, I would recommend hosting a web app (or creating an Electron app), and then communicating from that web app with the IoT devices. If you have some specific use case where you can't use HTTPS, but you believe you nevertheless have a secure application, I would recommend proposing an exception to the Secure Contexts specification instead; then, you can use all APIs that require a secure context in your application, not just Web Crypto. I'm not sure how such an exception would look, as it depends on the exact use case. However, I think this has a better chance of succeeding, if you can somehow show the user (agent) that the origin is secure, as this has the user's experience in mind. Shipping a web application over HTTP (which is nowadays shown by many browsers as insecure) and then somehow trying to convince the user that the application is secure anyway, will always lead to a suboptimal user experience. |
For example, see w3c/webappsec-secure-contexts#60. |
So your proposal is... no solution ? Hopefully, other people have solved this, and if I take OpenSSH as a example, use a different scheme: security is asserted on first connection and then some cryptographic signature is stored locally for subsequent connections. Right now, by forbidding browsers to offer a secure webcrypto implementation (one that can be relied upon in JS), you're providing exactly zero value to the world. In HTTPS, you can send whatever crypto code as JS and it'll be secure, you don't need web-crypto. In this situation, webcrypto's only interest is speed, and the main downside is complexity. If webcrypto were allowed in unsecure context, but with secure guarantees (like for example, being able to store a signature of some server's main script in local storage and have the signature asserted before running the script) you could provide a solution for the local internet issue that many of us are trying to circumvent. Take the following scenario:
Your position, as I understand it, is not to allow any kind of innovation in security scheme. |
No, my proposal is to solve this problem in w3c/webappsec-secure-contexts#60, instead of here. In that issue, someone proposed to consider local devices as secure origins if the user has indicated that they're on a private network. To me, that seems like a much simpler solution than what you're proposing, and is not specific to Web Crypto. |
I understand your proposal. But I don't see how it would solve the MITM issue if, suddenly, the LAN address space became a secure context. Since HTTPS security is based on a verification done with an external server (the CA), and on a local address space you can't have a CA, allowing 192.168.1.0/24 to be secure without a CA, means that any device could replace the some other device's web service and scripts by just impersonating/spoofing the other device's IP address. IMHO, I don't think it can be solved without changing the paradigm for local network: go from a central authority system to a decentralized trust system. Secure context does not solve the former (I'm probably missing something here?), and you can use web crypto to solve the latter. But you are right, it's probably not the right place to discuss this proposal. |
In the subclause "if the user has indicated that they're on a private network" is hidden the assumption that the user trusts their local network and the devices in it. For example, if you don't trust your own device, HTTPS is also not secure, as malware on your device can MITM that as well. Considering local devices as secure origins (if the user trusts them) addresses the use case that was brought up as then you can use Web Crypto (and other APIs that require secure origins). At the very least, it's not less secure than allowing Web Crypto to be used on HTTP in general ;) If you want more security than that, indeed a separate proposal would be needed. |
That's true. So why deny it at first ? |
What did I deny, exactly? I never argued against allowing Web Crypto on LAN. I was merely arguing against allowing Web Crypto on HTTP in general. |
I’ve been following this topic for years and am astounded at those few supporting the requirements for https, regardless of how prevalent it is. A good encryption library should not rely on having certificates from centralised issuing authorities, when it isn’t needed for that library’s internal logic. That’s insane. |
Ok, so that's where I disagree with you. Webcrypto should be allowed on HTTP, maybe only on LAN, but it should be accessible. Because on LAN, it's not possible to have HTTPS (unless without horrible DNS tricks and an internet connection, so a WAN). However having Webcrypto on HTTP anywhere else (WAN) doesn't decrease security (I think it's the opposite). Because when something needs to be done, it'll be done and we don't live in a world of unicorn and fairies. Without Webcrypto, the result is sending crypto code as unsecure JS, unauthenticated, uncertified. With Webcrypto, at least, the crypto toolbox is standard and secure, and not tempered. The code that's using these web crypto primitives can be modified by a MITM in HTTP unless some addition is added to the proposal/specification. With few modifications (like I've described above), it can even be made secure against MITM after first contact. It's not really complex to add, since we already have script's signature checking in browser (with subresource integrity specification), adding a secret per-browser salt token and a dictionary of token=>HMAC(script, secret||token) in local storage and using it before allowing the script to run is few lines of code, the most difficult part is to add a dialog to ask the user if she wants to trust the server initially (but again, we already have those for setting up bad HTTPS certificate exceptions). As you said, it can be a new proposal, I think it's too small to make a proposal, and I don't think it'll be baked up by Google, that's why I think it should be in this proposal. |
A crypto toolbox that's only doing what's already done/required in HTTPS is useless anyway, since you can already use HTTPS to send one to the browser. A crypto toolbox should allow making crypto algorithms and applications ever with a centralized architecture or a decentralized architecture. Right now, the specification is centralized only, since if Let's Encrypt server is DDOS, the whole web will collapse (and no, the fact that there are other CA is not a justification for decentralization, when one actor is free vs paying competitors, it's the main actor). To allow decentralization of the web, one should not rely on a technology that mandate a unique (or few) hosts to be alive, but instead provide way to trust other & any hosts and a crypto toolbox is mandatory to achieve this. It's a shame that webcrypto doesn't run on HTTP, because this large area of possibilities is denied to us. |
Yes, that's what I meant. And that's what w3c/webappsec-secure-contexts#60 is :)
Well - at the very least it should be outside of this issue :) As you'll notice this issue isn't even about allowing Web Crypto on insecure origins, it's about allowing Web Crypto on secure origins only. As that has been done, this issue is closed and will never be reopened. So if you want to have an open issue to discuss this stuff in, you should create a new one. But, apart from that, whether Google implements something doesn't depend on whether it's included in a big specification or a small one. And in fact, additions to this standard have to go through incubation, anyway, so you'd have to write a (small) specification anyway. But that's a good thing, not a bad thing - if you just sneak something into an existing specification, without gaining consensus on it, nobody will notice or implement it.
That's not entirely true. Web Crypto can be used to implement end-to-end encryption, which HTTPS can't offer. There are some challenges around trusting the code if you don't trust the origin, but that's again orthogonal to this issue. Additionally, in a web extension (which is also a secure origin), you can use Web Crypto to send encrypted data to a server if you trust the web extension but not the server, for example.
If it's your position that it should be possible to make secure decentralized web apps, then that's reasonable, however, for that you need secure code distribution, which comes before Web Crypto, not after. If you want to have a mechanism where the code is signed and trusted by the user with a trust-on-first-use model, that's potentially possible, but again the "index.html" should then be signed also (and the signature be verified by the browser). If that's implemented, then the origin could be considered as secure, and then Web Crypto could be used there. However, using Web Crypto (which is run by the code of the web app) to verify the code of the web app is not possible. |
That's probably the main point here. You don't need secure code distribution, unless you consider that the browser's internal code is a distribution. Secure code distribution is what HTTPS is doing and we can safely say it's working well, but it doesn't mean other way to distribute code over unsafe channel won't work. The trust-on-first-use is an example of a secure code assertion over an insecure channel. It requires a secure / non falsifiable tool and web crypto can provide it since it resides in the web browser, not on the code that's sent over the wire. There are other methods to send secure code over an un-secure channel, (typically TLS is one of them too). They all rely on a trusted implementation of some primitive and web crypto should be this implementation. It's not possible to verify the web app right now on HTTP but it can be made possible with 2 changes to the specifications:
So if you think it's worth it, I'll bootstrap another issue, but I don't know if it should be on this repo or on another one. |
Why was this even accepted :/ |
Bug 25972 from bugzilla:
As with service workers implementations want to require a secure origin in order to get access to cryptographic functionality. We should make that a requirement in the specification so that implementations do not have to reverse engineer each other.
In particular you want to refer to the origin of http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#entry-settings-object
Secure origin is defined by https://w3c.github.io/webappsec/specs/mixedcontent/
Ryan probably knows which flavor of secure origin is to be used here.
The text was updated successfully, but these errors were encountered: