Open d4l3k opened 10 years ago
This is functionality that has been discussed in the past, and an acceptable implementation plan was never submitted. There are some fairly serious issues that can arise and there needs to be a plan to mitigate those risks before I will entertain inclusion of any such mechanism within WebPG.
I can't find the previous discussion, but off the top of my head here is what I can think of:
When a site requests to sign or decrypt data, there is the possibility it is for fraudulent purposes. The site could have passed something for the user to sign, such as data used for authentication purposes elsewhere, or possibly encrypted data that was originally intended for another party.
Lets say a user encrypted some data (an email) to Party X and Y; this data could be sent in a hook for decryption by a website, resulting in a party other than X and Y having the plaintext result.
In another scenario, lets say that identification is established by "Some Service" by sending the user a nonce that is encrypted to the user, expecting the user to decrypt the packet, sign the nonce and return the encrypted result. This hook functionality could be used to introduce an authentication MITM.
If the intention is for an external website to initiate sign/encrypt/decrypt methods, the user has to be absolutely aware of where the request is coming from, the contents of the data being processed and the parties subject to reading the data (recipients).
It could become disruptive to the user experience if they are being presented with this type of information on navigation changes or hook requests, and worse, it could lead the user to become complacent about the data being processed. And that doesn't even mention possibility of a DoS attack, by flooding the user with requests that result in UI changes or multiple consecutive/continuous crypto requests (process intensive).
How does the user elect to enable said functionality? How do they manage this election (i.e. revoke it)? Per-domain rules? With a request from the site that intends to use it?
Where do hooks originate? Is this an event from the page or only from the extension it self? (for example, www-form with a key/value of "x-webpg-form-action='sign'", which is detected by the extension)
It would be helpful to gather the relevant use cases in order to devise a standard, create tests, execute implementation and audit the result.
While I do not argue the merit of the functionality, I believe that a comprehensive analysis of the possible issues needs to be done, and the framework should be designed accordingly.
While not crucial, I think this would provide a nice alternative to some of the other Javascript PGP solutions, such as: https://code.google.com/p/end-to-end/
This biggest benefit in using WebPG is that it allows native (thus fast) PGP and allows people to use their existing keys with no hassle.
The biggest security feature that would mitigate a lot of your issues is a permission system similar to those already in existence. On the page load, there would be a message sent to WebPG requesting access, the user would then be prompted.
It would be best to implement it to appear as native as possible to provide a unified user experience. The prefered way would be to use infobars, but they're currently experimental.
https://developer.chrome.com/extensions/infobars
A second choice would be to have a dropdown/menu appear asking for it.
I agree that there is a possibility for using a users PGP keys for fraudulent purposes, but the same thing could happen for almost any program that runs on your computer. Once the keyring is unlocked, native applications can sign and encrypt anything they want without notifying the user. In fact, native applications have access to gpg -a --export-secret-key
. WebPG would be more secure than a native application by limiting functionality to encrypting, signing, and decrypting.
The convenient--but not necessarily best--way would be to provide blanket full access to the encrypt, sign, and decryption methods. This is the only way I can think of for real time encryption.
For simplicity sake, each page should request the PGP permission with Javascript. For a more complicated system, some thing similar to a choice of "Grant (one time), Grant (domain), Deny". There would then be a list of permanently granted permissions in the settings page for webpg Time based permissions could also be implemented.
I believe that the event should originate from the page and not the extension. This would allow for more dynamic uses of encryption such as real time communication.
There are numerous use cases. Pretty much any case for encryption in the browser is applicable here, and Javascript encryption is notoriously bad.
I'm working on an open source version of Google Drive/Office 365, and am hoping to add end to end encryption for documents. https://websyn.ca/
@d4l3k
I agree that there is a possibility for using a users PGP keys for fraudulent purposes, but the same thing could happen for almost any program that runs on your computer. Once the keyring is unlocked, native applications can sign and encrypt anything they want without notifying the user.
In my opinion, this argument is fundamentally flawed, in that, programs that run on the system can be vetted by users; web content is not. It is feasible to mitigate personal risk in regards to applications by being conscientious about the types of applications installed and their trustworthiness. It is not feasible however, to do the same with web content, which is dynamic in nature and very much the target for gaining access to a users system and/or data.
UI Issues
The convenient--but not necessarily best--way would be to provide blanket full access to the encrypt, sign, and decryption methods. This is the only way I can think of for real time encryption.
That is not acceptable by any means, for the reasons stated in my first response to this issue.
Hook origination
I believe that the event should originate from the page and not the extension. This would allow for more dynamic uses of encryption such as real time communication.
I don't understand how this conclusion could be founded without first defining the acceptable use-case scenarios. In order to (intelligently) define the protocol of an API, I believe we are going to have to first establish what exactly the API is expected to do, and then define exactly how those methods are invoked. We cannot (in good conscience) provide an API of poor security design merely in the name of being robust. Each use-case should be carefully analyzed to determine - first and foremost - the safest manner in which to support it, and - secondly - the most robust manner in which to implement it. How the API hooks are triggered are also subject to the limitations, security contexts and available native functions within the respective browser (keep in mind, WebPG has support for browsers other than Chrome). I also do not envision that every use-case will utilize the same manner of invocation; it could be different depending on a number of factors, such as the potential severity of the operation, whether the operation is out-of-band or possibly even deterministic of user preference (i.e. white-list, etc).
I propose we slow down a bit and take this a step at a time. I think doing so will prevent speculative theory of operation and allow us to make more informed decisions about the specific areas. As I said before, I can see the value in supporting this functionality, but only by means of intelligent, security conscientious design.
So, to begin this process, I believe we need to first articulate the possible use-case scenarios (in detail) - such as, www-form encryption/signing, encrypted content decryption, signature verification, etc.
From there we can identify the (currently) feasible use-cases (they may change/grow over time) and analyze the specifics of those cases, such as viable permissions assignment, how to invoke these requests and where the final result goes (i.e. returned to user only, submitted to the requesting server, etc).
I've thought about it more and I agree my conclusions were a bit hasty. I also realized that the features I was looking to get out of WebPG aren't actually needed if paired with a standard crypto library.
I feel like I should explain a bit more about my personal use case. I wrote a fairly complete cloud document editing & file syncing suite similar to Google Drive and Office 365. One of the big thins is that it has real time collaborative document editing, and can be self hosted. The self hosting part provides some security for users, but I was hoping to add an option for encrypting the documents client side, thus making it impossible for the server to read people's files. I had envisioned two uses for WebPG. One being that it would allow user to sign their changes and prove that they have actually made them. This would require some sort of unfettered signing capabilities as the changes are sent as the user types (thus needing a signature every couple of seconds). The issue with this as you rightfully pointed out, is that it's possible to sneak in a malicious signature. I'm really not sure the best way to handle this.
The second use case I wanted for WebPG was full document encryption. This I originally had imagined to be solved with full access to WebPG for continuous encryption and decryption of messages sent between clients. Once again probably not the best method. I now realize that if you paired WebPG with a standard JS crypto library, you could have a symmetric key used for encryption/decryption of the document and encrypt the key using WebPG. This would require only a few WebPG requests. The first would be a decryption request when the document was loaded, and then a encryption request if adding another user to the document.
While the second use case is probably much more feasibly and secure than the first, being able to prove that a change was made by someone still seems to be an important use case. I'm wondering how feasible it would be to generate subkeys on a per domain basis. If we used signed subkeys, it would still be possible to prove the ownership of the key and provide encryption without the issue of malicious requests.
With regards to other use cases, I could see www-form encryption/signing being a useful thing, and probably being easier to implement while still allowing the user to verify all data being signed. However, since I'm a moderately selfish person, I'd rather focus on creating a secure javascript accessible API.
As far as I can tell, there's no way to use the PGP utilities from a normal webpage (unless I'm missing something). That's the biggest missing feature for my use case.
The only way I can currently see to do that is to use something similar to this. It shouldn't be too hard to implement as far as I understand. It should be possible to add another content script that listens for events and responds to them. The website that wants to use the API can then pass messages to PGP to encrypt/decrypt/sign things using webpg's default key.
I'm going to try and implement this in a fork, but I wanted to get other people's opinions.