11 ms·
Javascript Cryptography Considered Harmful
- rorrr 14y agoRandom number generator problem is solved in Chrome: var x = new Uint8Array(10); window.crypto.getRandomValues(x); console.log(x); It's also supposed to work in FF, but for some reason doesn't: https://developer.mozilla.org/en-US/docs/DOM/window.crypto https://developer.mozilla.org/en-US/docs/DOM/window.crypto
- ema 14y agoYou also have to ensure that "window.crypto.getRandomValues = function(y) {};" wasn't executed earlier.
- Drakim 14y agoHmmm, interesting. I think you can check if a function is native or not by casting the function to a string, and I don't think there are any native functions the attacker would stand to gain anything by swapping.
- csuwldcat 14y agoThere are a multitude of natively available browser functions that are immutable and cannot be CRUD'd. This guy really needs to understand more about the browser. His commentary on client storage in the browser also is myopic.
- jvdongen 14y agoAnd how are you going to be sure that 'window.crypto.getRandomValues' points to the function you expect? Currently you can't be.
- UnoriginalGuy 14y agoWhat does this have to do with what he said? He addressed one problem and then you bash him over the head with a completely different one.
- jvdongen 14y agoMy point is relevant as he considered the problem of availability of a CSPRNG 'solved' - and it isn't until you also solve most of the other problems Thomas identifies. And it was not my intention to 'bash' anyone - if it came across as such I apologize.
- makomk 14y agoTechnically you can't be sure that when you open() /dev/random in a native C application that it's actually opening /dev/random either. Yes, really.
- jvdongen 14y agoYou're technically correct - it's all a matter of degrees of certainty. That does however not invalidate any of the points made in the article. If that native C application runs on a server that is fully under your control you stand a far, far better chance then when that native C application (say a web browser) runs on some computer not under your control. Especially if that native C application is explicitly written to accept run-time addition of random third-party code (aka browser extensions).
- jQueryIsAwesome 14y agoYes you can be sure; using an iframe + innerHTML because the later one is not a function and can't point at one or can be defined any other way and the same goes for its parent objects. document.body.innerHTML += "<iframe></iframe>"; document.body.childNodes[document.body.childNodes.length-1].contentWindow.crypto.getRandomValues; And please don't talk about how the JS engione of the browser can be compromised too; I know that but here we are aiming for practical applications not a philosophical debate about how everything is just an illusion.
- willscott 14y agoAre there many examples of websites using client-side javascript cryptography?
- chewxy 14y agoI have seen (and shot down) people floating ideas of doing AJAX HMAC. It's a great idea if you think about it. But if you really think about it... it is a OHGODSWHY idea
- homedog 14y agoBig one recently: MEGA
- callahad 14y agoMozilla Persona's cross-browser shim does keypair generation and signing in client-side JavaScript.
- simcop2387 14y agoI've actually done client side HMAC before to keep from sending passwords in plaintext at least. The site couldn't do SSL at the time. Not perfect, easily MITM-able but at least not network sniffable.
- MichaelGG 14y agoAre there many scenarios where you can read, but not write, to a network? On WiFi, you can inject if you can read. On a switch, if you are reading via, say, poison ARP, you can also write. Passive taps like mirror ports can't read, but it seems that WiFi/Ethernet/some other physical thing is a more common vector in the first place.
- simcop2387 14y agoLikely not that many. Which is why it only prevents someone from being able to do a replay attack on the login form. (The server chose the secret for the HMAC). It made the better choice for attacking the site to be something more like firesheep to take over the session instead. Though I made that a little more difficult by rotating the session keys after every transaction, so if you take over it would force the other person to be "instantly" logged out and they'd notice and could do something about it (log back in and log out immediately would suffice). Not perfect but also not the worst way to do it (assuming they aren't injecting javascript into the client to do the work anyway, no way to prevent that over only HTTP).
- politician 14y agoWhy can't we build the necessary primitives into the browsers themselves? We have Web Audio APIs, file system APIs, no?
- thirsteh 14y agoIt's coming: http://www.w3.org/TR/WebCryptoAPI/ http://www.w3.org/TR/WebCryptoAPI/
- politician 14y agoAwesome! I hope it isn't marred by an attempt to close the default-open nature of web applications (they're looking for feedback on "potential missing functionalities to deploy secure web applications." Echoes of HDCP. Ugh.)
- daeken 14y agoNothing in the WebCryptoAPI has anything to do with locking down applications, but attempting to make them more secure (that is, making it more difficult to compromise their integrity). That said, it doesn't accomplish this; see my sister comment to yours.
- daeken 14y agotptacek (original author of the OP here) and I responded to the draft here: http://news.ycombinator.com/item?id=4549504 http://news.ycombinator.com/item?id=4549504 The tl;dr is: the trust model is broken, and low-level primitives exposed in the way that they are is begging for pain. Not a lot has changed since then, sadly.
- thirsteh 14y agoYeah, I am not very optimistic about the primitives being used correctly, or any kind of safety in face of e.g. XSS. At least you can read from /dev/urandom...
- politician 14y ago
- chris_wot 14y agoFor those interested in the "Radioactive Boy Scout" referenced in the article, a copy of the Harpers magazine article about David Hahn can be found here: http://www.dangerouslaboratories.org/radscout.html http://www.dangerouslaboratories.org/radscout.html
- cperciva 14y agoFor the same reason: If a backup service allows you to access your data via a web browser, it's not secure.
- aarondf 14y agoInteresting. Could you elaborate? Backblaze allows web access but only after I enter my key to "unlock" my files. Am I being hoodwinked?
- bigiain 14y agoIn the "government took control of the server some time ago without announcing it" case, once you've logged in and "given up your key", you're hosed.
- erichocean 14y agoIn fairness, any computer that has been physically compromised is no longer secure, period. Every attack against an otherwise secure system requires these two steps: 1. Compromise a computer or environment by gaining physical access and changing something about the computer/environment (e.g. creating a false passphrase screen, or installing a hidden camera). 2. Trick the user into giving up their passphrase/private key after step (1) is complete. Once a machine or environment is compromised, it's just a matter of time before (2) happens and your security is broken. Physical access to a machine or environment where a passphrase is entered is required because network security is (effectively) perfect with modern crypto. If you are truly paranoid, you'd have to constantly secure your environment and physical hardware, and whenever either went out of your physical control, not use your passphrase/private key. Full stop.
- dchest 14y ago"In fairness" about what? How is client's computer compromise related to server compromise? If someone gets access to, for example, Tarsnap servers, the attackers can do nothing apart from deleting your backups. If the same happens to Backblaze (who have some interesting understanding of "security", BTW: http://i.imgur.com/t3NCm3X.png http://i.imgur.com/t3NCm3X.png), they can get full access to your backups.
- erikpukinskis 14y agoThe author is really only saying browser cryptography is bad for one specific problem: securely transmitting data to an untrusted provider. But there are lots of other use cases. For example, maybe I want to upload a file to a server, and I trust them not to try to steal my data, but I don't trust my government not to confiscate their servers. In that case, SSL + browser cryptography is adequate to give me the assurances I need that the government won't be able to get access to my data, even if the service's engineers could.
- asdfaoeu 14y agoHe also ignores the situation where you want to upload it to an untrusted third party server where the javascript was obtained from a trusted server. Also the same problems of verifying the source exist in most closed source applications that automatically update so really nothing to do with javascript.
- haberman 14y agoSeriously, the article is badly mistitled. > And if you have SSL, why do you need Javascript crypto? Just use the SSL. Maybe because SSL only solves one problem, and other cryptographic algorithms/systems solve other problems?
- makomk 14y agoAlso, until recently SSL didn't support any kind of forward secrecy, and even now many SSL servers and clients aren't configured to use it. What this means is that if an attacker ever gets hold of an SSL server's old private key, they can decrypt any SSL sessions they've recorded which used that key. This makes security measures like JavaScript crypto which only protect against passive eavesdropping quite a bit more useful than you might naively expect.
- ema 14y agoBut if the government can confiscate the server they also can make it deliver modified JS. If you can't trust the server you also can't trust the JS it gives you.
- moonboots 14y agoThe problem with running crypto code in Javascript is that practically any function that the crypto depends on could be overridden silently by any piece of content used to build the hosting page. Ecmascript 5, the latest version of the Javascript standard, provides the ability to lock down the malleable runtime. Functions can be frozen so that no later code can overwrite or change their behavior. For more information, see this talk[1] by Mario Heiderich in 2011 or his slides[2]. [1] https://www.youtube.com/watch?v=yuNfO6I6pEA https://www.youtube.com/watch?v=yuNfO6I6pEA [2] https://www.owasp.org/images/a/a3/Mario_Heiderich_OWASP_Sweden_Locking_the_throneroom.pdf https://www.owasp.org/images/a/a3/Mario_Heiderich_OWASP_Swed...
- jvdongen 14y agoI'm afraid this falls in the "Check back in 10 years when the majority of people aren't running browsers from 2008." category ...
- greggman 14y agoThat's already true today. Chrome + FF have > 50% of the browser share by most measurements. Both auto-update. So does IE10. Which means the number of people with browsers running from 2008 is already below 50% and falling fast.
- jvdongen 14y agoTrue - but how is a web server with certainty going to decide which clients can be trusted (because they've a truly capable browser)and which are not to be trusted (because they have a vulnerable and compromised browser that just pretends to be capable and secure)? Of course it may be possible that one day there is a way around that issue, but currently there is not. Not even academically let alone practically. Hence Thomas's next remarks about the impossibility of 'graceful degradation' for crypto-in-the-browser issues.
- benatkin 14y agoInteresting points. I'd thought of these issues but hadn't heard them so clearly stated. I don't know if this situation would be common but I have an idea of where it could work. Perhaps a web app you completely trust could talk to an API you don't trust over CORS. The web app you completely trust would only talk to the api you don't trust over XHR and wouldn't eval anything it got back.
- dschiptsov 14y agoJust Cryptography?)
- Joeboy 14y agoRegarding the malleability of the js runtime, would this be addressed by making all the page content a single html+js file and making its hash widely available for manual verification? Obviously "normal" users aren't going to check it's kosher, but it should mean if a site's serving dodgy code somebody will notice. Obviously that's a bit impractical for most websites, but it could make sense for a site whose primary raison d'être is encryption.
- zachrose 14y agoInterestingly, this is exactly what the HTTP Content-MD5 header is for.
- martingordon 14y agoI am way out of my league asking this, but couldn't any MITM attack just fake that header as well?
- Joeboy 14y agoYeah, I don't think it actually solves any problems for us. It is, as zachrose says, interesting that it exists though. Also way out of my league, btw :-)
- el_cuadrado 14y agoIs it just me, or are they successfully killing a strawman in this article? Who the hell uses js cryptography for such things?
- DanBC 14y agoThis national UK newspaper has some javascript cryptography challenge response type stuff on their member login page: (http://users.guardian.co.uk/signin/0,12930,-1,00.html http://users.guardian.co.uk/signin/0,12930,-1,00.html) This website claims it's their script: (http://pajhome.org.uk/crypt/md5/ http://pajhome.org.uk/crypt/md5/)
- Sami_Lehtinen 14y agoWell, if you use native encryption software, what makes things any different? If they can replace key code and data on the fly for web application run over SSL, what makes think they're unable to deliver you fradulend updates for native apps? I have been raising alarm about this for a long time. Automated updates are dangerous, how many users make it absolutely certain that every update is secure? Well, I can tell you nobody ever does. Because secure updates or software doesn't exist at all. Even if the previous version was secure, the next version could be boroken by mistake or on purpose, or you could just get espionage version delivered which is made just for you. Unfortunately there are countless programs that do not make update delivery in very secure manner at all. Plain http, no signatures etc. That's quite much 100% fail.
- haberman 14y ago"WAIT, CAN'T I GENERATE A KEY AND USE IT TO SECURE THINGS IN HTML5 LOCAL STORAGE? WHAT'S WRONG WITH THAT?" "That scheme is, at best, only as secure as the server that fed you the code you used to secure the key. You might as well just store the key on that server and ask for it later. For that matter, store your documents there, and keep the moving parts out of the browser." This ignores the scenario of app deployment models like Chrome Packaged Apps, in which the JavaScript code gets downloaded up-front and then is only used locally. Since you don't re-download the code every time, you only depend on the security of the code once, up-front, instead of on a continuous basis. You aren't affected by server compromise (well, no more than compromise of your OS vendor, but surely you aren't arguing that we might as well send all our keys to Microsoft, Apple, and Canonical). Also I feel that this analysis conflates security with access. You may trust a company to keep their servers secure from compromise, but want them not to have access to the documents when the government comes knocking.
- DanBC 14y agoPrevious discussion (517 days ago): (http://news.ycombinator.com/item?id=2935220 http://news.ycombinator.com/item?id=2935220)
- pfortuny 14y agoErmh sorry to nag but after the google (et al) rogue certificates I think one would better say SSL is considered harmful as well.... Security is a set of layers and trade-offs. Harmful for what? That is the question. Your computer is considered harmful. Did you check the hashes of all the software you downloaded? Oh wait there are no checks to be done for the little app you got a couple of months ago... So: take an enemy and look if what you do is reasonable enough. Flying is considered harmful, hence the TSA. Remember the github fiasco? But you still trust them do you? I might (I do not) consider github harmful as well.
- pfortuny 14y agoDid I say anything wrong? Because to be honest, I think I was just laying bare some hard facts.
- sgdesign 14y agoA little off-topic, but was this written by patio11? The writing style feels very similar.
- DanBC 14y agoI think tptacek.
- jvdongen 14y agoThis piece has surfaced before. Then and now I see people coming out of the woodwork with seemingly smart ideas about how it still should be possible to safely use crypto in the browser one way or another. One of the things my company does is security testing of web applications. Regularly we encounter 'creative' use of cryptographic techniques (both in the browser and server-side) and each time it makes the hacker in us smile, because we know it is not a matter of 'if' we'll crack it but 'when' we'll crack it. Good crypto is a roadblock, bad crypto is just a challenge. And although it is very hard to decide if the crypto is 'good (enough)', the 'bad' is usually glaringly obvious. With the current state of crypto in the browser - just forget it. That's what Thomas is trying to get across: forget it - if you think you've found some smart way around one of the weakness he addresses, you're very most likely wrong. And even if you seem to have got it right, you're probably wrong still without anyone realizing it (yet). Same is true for building a crypto-system from primitives. Use what's out there, designed by the few people who know what they're doing. Remember: from the defensive side you need to get everything right. As an attacker I only need 1 hole. That's what makes it "capital-H Hard".
- haberman 14y agoI don't know if you're referring to my comment or not (http://news.ycombinator.com/item?id=5123674 http://news.ycombinator.com/item?id=5123674), but I was not saying anything about what is safe. I was merely objecting to false equivalences that the article was drawing. To say that localStorage is literally no better than server-side storage is a strong statement, and one that does not appear to be literally true. Taking issue with that equivalence is not the same as saying that any particular system/design is safe as a whole.
- jvdongen 14y agoI was not referring to your comment per se, but indeed your comment fits the general sentiment I was referring to. And I think that localStorage is indeed literally no better than server-side storage. Whether it is any worse depends on the situation - but better it is not. "This ignores the scenario of app deployment models like Chrome Packaged Apps, in which the JavaScript code gets downloaded up-front and then is only used locally. Since you don't re-download the code every time, you only depend on the security of the code once, up-front, instead of on a continuous basis. You aren't affected by server compromise (well, no more than compromise of your OS vendor, but surely you aren't arguing that we might as well send all our keys to Microsoft, Apple, and Canonical)." It's true that you do not re-download the code every time. Still, the trustworthiness of the code you received initially depends on the trustworthiness of the server you received it from. So you say, "but what if I have reason to trust it initially and not later on?", e.g. when the government comes knocking. Well, there are two things to keep in mind in that case: a) you download other stuff with your browser. Stuff that can influence the environment where your secure and trusted packaged app runs in. See also comment of zimbatm - even if it is not formally meant to be that way, in practice there are bound to be ways around any limitations - sandboxing in browsers is still nowhere near perfect unfortunately. Server security is not entirely peachy either, but at least on a properly secured server only a limited, carefully screened set of applications is allowed to run which makes things hell of a lot easier. b) Chrome packaged apps support auto-updating, so unless you take steps to prevent that from happening, you're never sure you're running the same version today as you did yesterday. Again, trusting the server to serve you a trustworthy version of the app repeatedly. And if you're trusting the server already, local storage is no better than server side storage. So I guess you could say local storage is better than server side storage (for some definition of better) if you run one and only one packaged application ever in a specific installed browser in an isolated environment. The browser + locally installed web app then effectively becomes a natively installed application without an Internet dependency. More secure indeed, but kind of defeating the purpose of that whole web thing ;-)
- exDM69 14y agoJavaScript, and all other crypto code not done with native code is not safe, for a reason not mentioned in this article: side channel attacks. When attempting to create crypto code using an interpreter or a byte code virtual machine, additional side channels are created by the differences in the execution compared to executing native code. Crypto code should be written in Assembler or C code where the assembly output is reviewed by the author. This is the only way to create code that does introduce side channel information that can be used with timing attacks, cache attacks, branch predictor attacks, etc. This introduces a problem because it takes a cryptographer and a hardware architecture expert in the team to write safe code for cryptographic primitives. This does not mean you can't safely use crypto from interpreted languages, as long as the cryptographic primitives are good native code.
- jakozaur 14y agoUsing the same logic, you need also review CPU and hardware since it may contain backdoors or other intentional insecurities. Even worse, there are allegations it's already happening: http://hexus.net/tech/news/cpu/40037-china-made-us-military-chip-security-backdoor/ http://hexus.net/tech/news/cpu/40037-china-made-us-military-... Of course, changing the interpreter seems to be an order (or two) of magnitude easier than supplying malicious interpreter. However, I would argue that if you are able to replace JavaScript engine you could do same with whole browser, so SSL is also worthless...
- deltasquared 14y agoWhat is magical about C code, or asm, or microcode that makes it more secure? Everyone has to trust someone. See the Ken Thompson hack: http://c2.com/cgi/wiki?TheKenThompsonHack http://c2.com/cgi/wiki?TheKenThompsonHack
- hedgie 14y agoa timing or voltage dependence on the key used for the encryption/decryption is often exploited by side channel attacks. this dependence can be used in some sophisticated attacks to reduce the key space dramatically. c and asm/microcode are close enough to the hardware that the operations let you analyze potential side channel leakage. for instance, if i look at the generated assembly it's possible to reason if the time/voltage used by the decryption operation is a function of the key used in the decryption. when a virtual machine is introduced the just in time compilation itself may introduce these dependencies between timing/voltage and the key used in decryption even if the source code does not appear to. however, unlike in c, you can't just go examine the compiled assembly to ensure a timing attack wasn't added by the compiler. the actual native code becomes a function of the virtual machine installed. the guy above you knows what he's talking about.
- vy8vWJlco 14y agoI agree that browsers simply don't have consistent enough APIs for the strong guarantees required for encryption, including strong random number generation and memory allocation behavior. That was the takeaway for me when I read this the first time. The "if SSL, why JS crypto?," DOM, and "chicken-v-egg" trust problems seem more like straw-men and sophistry though. Desktop crypto underwent an iterative evolution with early adopters bearing the bulk of the risk too. (Mega got the digest part wrong, but they fixed it, for example.) SSH doesn't use certificates, but you can read the host fingerprint and follow the chain of trust that way. If people are going to use crypto, they have to take responsibility for these pieces, which is improbable en masse. "[T]he security value of a crypto measure that fails can easily fall below zero" definitely rings true. Repeated malware infections, however, suggest peope don't even learn after they are burned... "Normal users" can't be bothered to update their browser or verify trust (leading to VeriSign having complete power, for example), for the same reason "normal" people don't use the existing native encryption (GPG/PGP) and, if they did, there would be no need for JS crypto.
- gingerlime 14y agoThere are some good examples and arguments there, but to me it reads like it mostly boils down to having SSL, which does quite a good job at solving the chicken/egg situation. You can have a good degree of assurance that you talk to the right server, and that your communication to it is not in the clear (of course, what's good degree is debatable, and depends on what you're trying to protect and against whom). I don't quite get why > You could use SSL/TLS to solve this problem, but that's expensive and complicated You can get an SSL trusted certificate for a few bucks, and installing SSL is probably one of the most well-documented sysadmin procedures on the web. How can it be more expensive or more complicated than implementing your own javascript crypto?
- acqq 14y agoIf you'd heed the author's warning, you wouldn't do anything of any meaning in the browser: no online banking, no purchasing... Because even if you don't do "crypto" (in the sense of encrypting/decrypting primitives) everything else you do also relies on the same TLS and JavaScript. My online banking site uses, of course, JavaScript. My online trading platform uses JavaScript. If the browsers and the sites are vulnerable to the attacks he presents (cross side scripting, man-in-the-middle possibilities, code injection attacks from another souce) then it's irrelevant if you do crypto primitives or not, you are vulnerable. On another side, if you assume that other vulnerabilities don't exist, and you do such things online like banking or trading, and you accept that the sites use JavaScript, I don't see any argument why the crypto primitives which run in addition to the rest of the code, everything delivered over TLS and from the same site, are any more suspicious than the rest of the JavaScript. The advantage of the encryption on the client side is obvious. Of course, it would be even better to have the client side encryption controlled by the user separately from the site. But under assumption that I personally control the server from which I deliver my html and JavaScript over TLS, I still feel better having the possibility to encrypt something that I'll upload to the server as long as I assume that the browser is not attacked. The only thing missing is the possibility to somehow checksum the delivered html and code and then "lock" that in my browser. It's not something scalable, I know. But the problem is never that much technical as it's "political." Consider Dropbox: in many use cases, they would be able to have all the encryption on the client and not to deliver the key to them. However they do deliver the key "because the users will need it." Who says that? They, and I can't choose. Technically, the solution can be certainly achieved, the problem is that it's not an interest of the current service providers. Maybe is Mega the first one that really has such interest?
- trekkin 14y agoMega is not the first one. AES.io (my company) and several others have been available for some time. Mega is the first one to bring client-side JS crypto into public discussion.
- pfortuny 14y agoHonestly, being downvoted for being clear does not show a great intelectual clarity. Really: do you people check all the hashes of your software? Do you trust all the certificates in your browsers? Have you really honestly checked all the ssh fingerprints of the servers you connect to? I repeat: security is not abstract, it depends on the problem and the trade-offs. If this hurts please check your mind. And feel free to downvote OF COURSE. Be happy.
- Flenser 14y agoWhen was this written? The only date I see in it is this: Check back in 10 years when the majority of people aren't running browsers from 2008. Edit: The oldest version on archive.org is Sep 2011, so it's at least 16 months old. http://web.archive.org/web/20110815000000*/http://matasano.com/articles/javascript-cryptography/ http://web.archive.org/web/20110815000000*/http://matasano.c...