
Javascript Cryptography Considered Harmful - adgar
http://www.matasano.com/articles/javascript-cryptography/
======
tzs
Minor quibble:

    
    
       WHY CAN'T I USE TLS/SSL TO DELIVER THE JAVASCRIPT
       CRYPTO CODE?
    
       You can. It's harder than it sounds, but you safely
       transmit Javascript crypto to a browser using SSL. The
       problem is, having established a secure channel with SSL,
       you no longer need Javascript cryptography; you have "real"
       cryptography. Meanwhile, the Javascript crypto code is still
       imperiled by other browser problems
    

My minor quibble is that there are other reasons one might want cryptography
besides establishing a secure channel, and so using SSL does not necessarily
solve whatever problem one was trying to solve with JavaScript.

For instance, the client might need data that is stored encrypted on the
server, and you want to do the decryption on the client.

~~~
dfox
There is one (and probably only one) case when js crypto makes sense. And that
is when server operator wants to convince third party that he cannot access
encrypted data at rest stored on the server. Client side JS based encryption
(and by the way also things like hushmail) does not help in any way when you
don't trust the server.

~~~
jimktrains2
> And that is when server operator wants to convince third party that he
> cannot access encrypted data at rest stored on the server.

Or the server actually doesn't want to store unencrypted data.

------
LiveTheDream
I found this quote as telling as it is hilarious:

> Just as all programs evolve towards a point where they can read email, and
> all languages contain a poorly-specified and buggy implementation of Lisp,
> most crypto code is at heart an inferior version of PGP.

------
d2
Delivering cryptographic software via a network, having it run in a "maleable"
runtime and creating a user expectation that it will be secure, is not new.

We've been doing this on the desktop for years.

I'd like to pose a question to the authors:

Don't all the premises you've based "Javascript Cryptography Considered
Harmful" on apply equally to downloaded desktop software?

-A chicken egg problem

-A malleable runtime for apps with admin access

-Code verification being defeated by other hostile apps on the system

-Inability to trust the secure keystore because of the chicken-egg problem and other hostile apps installed prior to the crypto app's installation.

-The weakness of pseudo-randomness

~~~
yuhong
Downloaded desktop software is generally written in a compiled language like
C, and for example can't easily be XSSed to inject JavaScript.

~~~
__david__
Yeah but C has its own problems--buffer overflows and the like. Just because
it doesn't have _exactly_ CSS doesn't mean it lacks similar problems.

~~~
tptacek
We're talking about "problems" in the context of "things that make
cryptography hard". The other security flaws of C/C++ are orthogonal to this
issue.

This isn't a value judgement on Javascript. I like Javascript. The hard fact
of the matter is, not every good programming environment is going to be
suitable for cryptography.

~~~
__david__
Perhaps, but almost all buffer overflow, remote code execution bugs are _very_
similar to XSS attacks--feed the program something it doesn't expect along
with some junk for it to execute. The mechanism is different but the concept
it the same.

~~~
tptacek
No, the concept is not the same. C programs aren't designed to execute code
from third parties.

------
michaelchisari
Which is why encryption should be something that the browser handles
internally. This is something I proposed recently:

[http://wiki.appleseedproject.org/doku.php?id=future:encrypti...](http://wiki.appleseedproject.org/doku.php?id=future:encryption:client-
side_encryption)

(Note, originally in this proposal, I support the idea of using a browser
plugin, although now I think it should be functionality baked directly into
the browser)

By adding an encryption="" attribute to the html markup, and the user
instructing the browser on how to utilize a private key on their system, you
can encrypt and decrypt data in the browser, without requiring a trusted
server.

~~~
starwed
Something like that seems horribly hard to get right.

Forget about cross domain scripting attacks, now you can't trust JS _from the
point of origin._ Yet at the same time, you'll probably want it to be able to
do all sorts of fancy AJAX-y stuff on the decrypted content. (Certainly on
other parts of the page.)

~~~
michaelchisari
You're right, in order to get the security right, you wouldn't be able to
access the decrypted content with javascript. The browser would prevent that
from happening.

Yes, potential functionality would be lost, but that's always part of the
trade-off for security.

But I don't think the trade-offs would be detrimental, from a usability
standpoint.

~~~
jbri
From a user perspective, how would you identify "safely" encrypted elements,
in a way that can't by spoofed by the page rendering a nonencrypted element
with appropriate styling?

~~~
michaelchisari
Could be the same way the browser identifies "safely" implemented HTTPS (ie,
popup, icon, etc). A nonencrypted element with appropriate styling would not
have the same browser-level indications that an encrypted element had.

------
LogicX
Since no one has brought it up yet -- I figured I would. The entire time I
read this article, I was thinking of Clipperz (<https://www.clipperz.com>)

Their entire product is based on the model of in-browser cryptography of your
credential payload.

You can read more here: <http://www.clipperz.com/security_privacy> and
numerous blog entries, and other articles around the web, but its open source,
so you're welcome to review it yourself.

The basic premise is that your browser, through javascript, deals with
encrypting and decrypting a blob object which is stored on their server,
transmitted via SSL, which they can't read, and can only be read by you when
your browser decrypts it with javascript.

I'd love to see the author's take on the Clipperz implementation.

~~~
marshray
(note: not the author)

At first glance, without going so far as to create an account, they do a lot
of stuff right.

I note that the HTTP session cookies set pre-authentication are not 'secure'.
I.e., they can be be sent in-the-clear for HTTP connections as well. This may
or may not be a real problem in practice.

------
taybenlor
I'm throwing a rock into the ocean here with all these comments. But I feel
like the entire assumption of the article ie "SSL is expensive + hard". Is it
really?

All the big companies are making the change to SSL. Sure it may seem
expensive, but how many engineer hours will you throw away on cutting those
costs? Will those hours have cost you even more? Further: what is the cost if
your engineers' implementation is poor and easily broken?

You spend money on SSL, SSL tech gets cheaper and faster. Rinse, repeat.

Or am I missing something?

~~~
tptacek
I wrote the article and I don't think TLS is hard.

~~~
marshray
I'm not trying to be a twit here, but be fair to the site admins: say that
after *.matasano.com works fully under https without any mixed-content
warnings.

E.g., <http://www.matasano.com/> sources <http://use.typekit.com/zpb4ovg.js>.
But there's no <https://use.typekit.com>. How are you going to fix that? It
takes a village.

~~~
tptacek
Just do be clear: WWW.MATASANO.COM is a static brochure site and we don't do
any HTTPS on it at all.

------
benregenspan
"There are three misconceptions embedded in that common objection, all of them
grave."

I completely agree with this article, but why do so many security researchers
try to write like cartoon samurai?

~~~
tptacek
I don't think it reads like "a cartoon samurai" (but then I don't know how
samurai sound). What you're really noticing is how lazily written it is. That
whole article is a single draft I wrote almost a year ago and never touched
again.

You're seeing it because I was too hung over this morning to repeat all the
arguments it contained when Javascript crypto came up on HN.

I didn't submit the article as a story; in fact, I've been sort of dreading it
being submitted ever since I wrote the comment that had the link in it.

~~~
sneak
Don't dread, it is clear and factual and free from obvious typos. You've even
got a jwz quote and radioactive boy scout references - I rather enjoyed it.

~~~
Natsu
Oddly enough, that's one of the parts that could use a bit of editing:

"Ever read the story of the radioactive boy scout? He bought an old clock with
painted with radium and found a vial of radium paint inside."

------
dave1010uk
Most browsers (including mobile ones) except IE support the <keygen> HTML
element [1]. This creates a "secure" keypair. The public key can be sent to
the server and the private key is stored locally somewhere (I guess gnome-
keyring, Mac Keychain or Windows registry). I haven't ever seen this in use
except in technical demos. While this can't be used for many things where JS
encryption is in use, I'm sure it deserves more recognition than it currently
has.

[1] <https://developer.mozilla.org/En/HTML/Element/keygen>

~~~
gizzlon
This alone would not be enough: How do you now the answer you get is coming
from the server and not someone who stole the public key?

------
shazow
The vulnerability of implementing crypto with in-browser JavaScript seems to
be coming up more and more in the past year.

Tl;dr: A MITM could serve you a fake implementation of said crypto and you
could very well be encrypting your content with ROT13 while thinking you're
getting some NSA-grade security or what have you.

My initial instinct is "browsers should expose some native crypto functions
which have always-preceding namespace priority" but after thinking about it
more, it doesn't matter. The attacker could just push code that leaks data
before it even hits the crypto functions.

Looks like the only workaround is to use SSL/TLS.

(This is all assuming that the implementation of the crypto is solid, of
course.)

~~~
dublinclontarf
Unless the JS is served over ssl/tls then it is vulnerable to a MITM modifying
the code en-route.

Throw in ssl and that fixes that problem.

An interesting example of this is glbse.com, it's a bitcoin stock exchange, on
the site there is a client python library and a JavaScript client application
(to run in the browser).

Putting aside how poorly documented (and designed) the JS client is, what they
use it for is authentication/authorisation not... for actually encrypting.

All requests from the JS client are signed with a RSA private key, the server
keeps a copy of the public key, and verifies any incoming requests.

The private keys can be stored in html5 local storage (encrypted if you want).

The keypairs are initially generated on the server.

When they first started making this available it was being served over plain
text http, now they use SSL for the reasons above.

The idea is to remove the need for servers to store username/password
combinations. The users account ID is a sha256 hash of their public key.

<https://glbse.com> and the JS client <https://glbse.com/client/glbse/> as I'd
said the UI on this is terrible, but it's something they're working on.

~~~
fadzlan
That said, as other commenter has mentioned, should the server be compromised,
the JS crypto lib may be overwritten with something else that steals the
decrypted content in the browser.

The thing is, the browser still depends on the server for the crypto
implementation EVERYTIME the user logs in to use the application.

Native application also suffers from this, since any downloads of the native
apps still depends on the hosting server not being compromised. However, the
vulnerability only applicable when the application is being download, instead
of over and over again in each time of usage as in the case of web
application.

The only way I can think of is of using extensions. In this manner the trust
issue happen once during the download of said extension. By doing this, the
implementation would be almost as secure as native application.

Almost as secure, because web pages are still content+execution. For the
solution to be secure, the pages needs to be secure itself, since other
Javascripts or the implementation of the web app could may not protect the
user from XSS based attack.(You could say the same about native apps though,
as the security depends on how secure is the codes against things like buffer
overflow).

I personally thinks that it would be the best bet right now.

------
magikarp
It is ridiculous that even in light of the COMODO HTTPS hack, the writer would
go as far as to say that SSL/TLS is a better solution.

The writer also ignores that there _are_ potential solutions to many of the
problems pointed out: In case of random number generation, check out
seedrandom:
[http://davidbau.com/archives/2010/01/30/random_seeds_coded_h...](http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html)
And while it's true that the server may always send "poisoned" JavaScript
code, projects that heavily depend on such code, such as Cryptocat, now ship
browser plugins that perform integrity checks on the code for you:
[https://chrome.google.com/webstore/detail/dlafegoljmjdfmhgoe...](https://chrome.google.com/webstore/detail/dlafegoljmjdfmhgoeojifolidmllaie)

Furthermore, and most importantly, by using SSL/TLS, the data being sent by
the browser to the server is encrypted as it passes through the network, but
however _remains readable by the server when it reaches it._ Whereas with
client-side JS crypto, the server cannot read the sensitive data. If the
writer does not trust the server to send correct JS code, how can he trust it
with the sensitive data itself, in plaintext, which is what he is doing by
using SSL/TLS? As I mentioned above, there exist browser plugins for a few
projects to verify the integrity of the JS crypto they use.

~~~
adgar
SSL/TLS _is_ a better solution. I find it ridiculous you suggest that browser-
based JS is _better_ , frankly. Comodo was breached and the certificates were
revoked using the theoretically-sound, tested, and implemented PKI solution.
While you do well to point to existing attempts to work around JavaScript's
deficiencies, it's genuinely surprising you could say they exceed the
capabilities of SSL/TLS.

~~~
magikarp
What about sslstrip? What about the fact that CAs are being hacked left and
right, and that governments such as China are known to produce fake certs to
wiretap dissidents? What about the fact that the server _can still read your
data?_ Again, how can you trust the server with your plaintext if you can't
trust it to serve you good JS crypto code? There have been attempts to
mitigate this problem in JS crypto anyway, using browser plugins that perform
integrity checks.

~~~
jbri
> What about the fact that CAs are being hacked left and right, and that
> governments such as China are known to produce fake certs to wiretap
> dissidents?

This is an authentication and a trust issue. JS crypto does not solve this at
all.

> What about the fact that the server can still read your data? Again, how can
> you trust the server with your plaintext if you can't trust it to serve you
> good JS crypto code?

If you don't trust the server, why are you sending it the data? And how is JS
crypto any better?

If you're trying to bash SSL to promote JS crypto as a better alternative, you
should probably _choose problems that JS crypto doesn't also have_.

> There have been attempts to mitigate this problem in JS crypto anyway, using
> browser plugins that perform integrity checks.

This isn't JS crypto. This is "browser plugin crypto, that we're choosing to
compromise by tacking on a huge JS part that someone can backdoor".

~~~
magikarp
> If you don't trust the server, why are you sending it the data? And how is
> JS crypto any better?

JS crypto remains better since there exists techniques to verify the crypto,
and _the server does not receive plaintext._

> This isn't JS crypto. This is "browser plugin crypto, that we're choosing to
> compromise by tacking on a huge JS part that someone can backdoor".

That's ridiculous. Integrity checks exist for many crypto-systems, don't
perform crypto - they are an extension.

~~~
jbri
> _JS crypto remains better since there exists techniques to verify the
> crypto, and the server does not receive plaintext._

You are giving the plaintext to code that has (at best) the same trust level
as the server itself.

What data is it safe to give to that code, that isn't safe to send (in a way
that can't be mitm'd) to the server?

> _That's ridiculous. Integrity checks exist for many crypto-systems, don't
> perform crypto - they are an extension._

I'm not sure what you're saying here - you might want to clarify exactly what
you mean.

In doing so, perhaps you could tell me why you think "browser plugin validator
+ untrusted JS crypto code" is more secure or otherwise better than "browser
plugin crypto with no JS".

~~~
magikarp
Don't get me wrong, browser plugin crypto probably works fine, but it's also
possible to use a browser plugin to turn untrusted JS crypto code into trusted
JS crypto code. The plus side of that is that the crypto code would still work
without the plugin.

~~~
jbri
So your answer as to why JS+validator is better than a plugin doing crypto is
that "it still appears to work fine even when the system is utterly broken".

...

When it comes to security, that is actually a _negative_.

~~~
magikarp
Whether you consider it "utterly broken" or not without the validator depends
on your trust of the server - similarly to HTTPS, which is vulnerable from the
trust standpoint thanks to CA vulnerabilities.

Furthermore, it's possible to verify the code manually, although tediously,
whereas a CA impersonation is perfectly transparent and very difficult to
detect. The validator plugin usually does the job.

~~~
jbri
...and your trust of the network itself, unless you're using HTTPS _in
addition_ to your ad-hoc solution.

And vulnerabilities in the trust chain are not HTTPS vulnerabilities - they
are trust chain vulnerabilities. It's straightforward to address them yourself
simply by _not trusting_ any CAs you don't trust.

~~~
magikarp
> unless you're using HTTPS in addition to your ad-hoc solution.

Yes, I don't see why not.

> It's straightforward to address them yourself simply by not trusting any CAs
> you don't trust.

From that standpoint, we're assuming that everyone with a browser knows what a
CA is and discerns between trustworthy CAs. I could equally say that it's
straightforward for users to simply review the JavaScript code they don't
trust - but the problem is that there exist many users who don't know how to
review JavaScript and don't know what a CA is, and will just rely on what
their browser tells them (which is where a plugin comes in handy.)

~~~
jbri
Why is a plugin trustworthy where the root CAs are not?

~~~
magikarp
Simply because a plugin can be verified locally at length whereas a
compromised CA can issue a fake cert that is very, very difficult to detect.

~~~
jbri
> _but the problem is that there exist many users who don't know how to review
> JavaScript and don't know what a CA is, and will just rely on what their
> browser tells them (which is where a plugin comes in handy.)_

> _a plugin can be verified locally at length whereas a compromised CA can
> issue a fake cert that is very, very difficult to detect._

Which is it?

Either you're claiming that verifying a plugin is easier than not trusting CAs
that you don't trust, or you're arguing two completely contrary positions.

edit:

And this then brings us back to the earlier point, which is _why not just use
the plugin for crypto in the first place_?

~~~
magikarp
Um, no.

The plugin is the same for all users - not everyone who downloads and runs
GnuPG knows how to verify it - but some people might go as far as to either
compile it from source or ever decompile it. If they find something
suspicious, they will report it so that other people who have downloaded the
software can be aware. Same thing goes for the plugin (except that the plugin
is easier to verify than a compiled binary.)

When I talk about people who can't review JavaScript or CAs, I'm talking about
the average computer user. I am not saying that "verifying a plugin is easier
than not trusting CAs that you don't trust." The average computer user doesn't
care about CAs _or_ JavaScript.

My point remains: a plugin can be verified by others who have downloaded it -
a compromised CA is extremely difficult to detect.

~~~
jbri
So once again:

> And this then brings us back to the earlier point, which is _why not just
> use the plugin for crypto in the first place?_

~~~
magikarp
I'm sorry, but I've already answered this, as a reply to one of your own
comments. Please scroll up.

~~~
jbri
And I disputed it, which is what lead us here. You are literally making a
circular argument by trying to use your answer to support itself.

~~~
magikarp
It's you who's being circular, sir.

------
antimatter15
It's easier for an attacker to passively observe a stream than to actively
inject specifically tailored code into it.

At least with JS Crypto, amateurs with Wireshark and Firesheep probably can't
steal your stuff. But since that's all the protection it offers, it shouldn't
be advertised as anything more ("This NOTEr 2.0 App uses AES-256 in JS over
HTTP to provide NSA GRADE security and privacy!"). In that sense, it probably
causes harm to use JS crypto, but JS crypt isn't absolutely ineffective.

~~~
tptacek
No, it isn't. It's actually harder. To intercept a stream, you need only
capture a few packets. To passively observe it, you have to position yourself
in a place that sees all the packets.

~~~
storborg
You're talking about computational difficulty. He's talking about practicality
for people who aren't experts. AFAIK there is no browser plugin that you can
download that will help you MITM an HTTP session, whereas there is a browser
plugin that will let you passively capture plaintext from said session.

~~~
tptacek
No, I'm talking about practicality. An attacker can intercept a session simply
by controlling any part of the DNS resolution chain. An attacker can passively
observe an entire session only by being situated somewhere in the actual path
between the victim and the server.

~~~
storborg
And how do you do that at the corner Starbucks without using the command line?

Edited to clarify since apparently I can't reply to a child comment: There are
tools that require next-to-no technical expertise to passively observe HTTP
sessions. There are no such tools that I'm aware of to execute an HTTP MITM
without control of the network infrastructure.

I think what the original poster meant was basically just "in a situation
where you absolutely, definitely, cannot have SSL, javascript crypto is an
iota better than nothing, because at least it breaks Firesheep and Wireshark".

~~~
tptacek
What do I care whether there's a pretty UI for an attack?

HTTPS/TLS is designed to be secure against adversaries with millions of
dollars dedicated to attacking it. Why am I even dignifying systems that rely
on the attacker's inability to use a command line, or write Perl code?

Have you reasoned through how much code it would take to make a "Firesheep"
that worked against Javascript crypto implementations? It's not even a little
bit hard.

~~~
wisty
This sounds like the US military's rational for not scrambling video feeds,
and using armour piercing rounds in the Middle East. The Soviet Union can
unscramble insecure cryptography, and their soldiers will have armour, so
insecure encryption and non-armour piercing bullets are considered harmful.

JS encryption is certainly less secure than SSL, and may give a false sense of
security to people who want to use it as a replacement.

On the other hand, it may be better than nothing.

~~~
rmc
_US military's rational for not scrambling video feeds_

Bruce Schneier wrote about why encrypting the video feed of predator drones
was not as straightforward:
[http://www.schneier.com/blog/archives/2009/12/intercepting_p...](http://www.schneier.com/blog/archives/2009/12/intercepting_pr.html)

 _The command and control channel is, and always has been, encrypted --
because that's both more important and easier to manage. UAVs are flown by
airmen sitting at comfortable desks on U.S. military bases, where key
management is simpler. But the video feed is different. It needs to be
available to all sorts of people, of varying nationalities and security
clearances, on a variety of field terminals, in a variety of geographical
areas, in all sorts of conditions -- with everything constantly changing. Key
management in this environment would be a nightmare._

------
amalcon
I mostly agree with the gist, but it's not really the Javascript that's the
problem. It's trying to do crypto in code downloaded over the network.
Implementing crypto in a Flash/Java/Flex/Silverlight/other flavor-of-the-month
applet has all the exact same problems. Well, you might have a secure RNG
(doubtful), but apart from that the problems are all the same.

Likewise, it's probably possible (though very difficult, and still not a good
idea) to have good crypto in JavaScript as long as it's either server-side or
built into the client.

~~~
tptacek
Java crypto doesn't have all the same problems; the Java plugin environment
has enough code to run crypto inside of it, and Java applets are (or can
easily be) self-contained enough to verify integrity. Browser Javascript (and
by extension Flash) is a uniquely hard place to make crypto work.

~~~
amalcon
If by "has enough code to run crypto inside of it", you mean "the SSL support
and the javax.crypto library", sure, it gives you some useful stuff. You can
also access all that stuff from JS without ever writing a line of Java code,
so that's a wash.

As far as self-contained Java applets go, every attack that can be used
against JS can be used against Java. It's a trivial exercise to instrument any
method call you like, including calls to any method that attempts any kind of
verification. Java bytecode is really quite transparent.

------
glenjamin
I don't see how implementing (correctly) an already known one-way hashing
function (SHA/MD5 for example), and then using this to form part of a basic
challenge-handshake protocol is not better than sending the password over the
wire.

In this way the attacker would be unable to gain anything useful from seeing
the challenge or handshake packets, and the only remaining vector is some form
of keylogger.

Or am I missing something here?

~~~
amalcon
Challenge-response hashing in JS is MitMable and likely to have implementation
errors.

SSL has defenses against MitM attacks, and is implemented in very widely-
deployed libraries, so if there's an implementation error you'll hear about it
before it's used on you.

The drawback is of course that you need to have a signed key. That is the
price you pay for MitM resistance. We're not supposed to use self-signed keys
(which are free), even though they are strictly better than JS
challenge/response hashing.

~~~
yuhong
Huh? If the session is MitMed, the plaintext password can be revealed, since
encryption is not one-way.

------
nikcub
In the usability/security tradeoff security companies will always try and
scare you to the right (they make money doing so). most developers are
comfortably being in the middle - after all, do we really need to implement
signed client javascript (with all the problems and centralized infrastructure
that imposes) just to store todo items?

------
sullof
I seem that this article contains a lot of good points about Javascript
cryptography. The error of the author is that he is unable to see a reason to
build a secure application based on Javascript because his prejudices are too
strong. I am the founder of Passpack. We use Javascript cryptography from
2006. We have 16,000 active users and nobody ever reported loss of data. I
think that if you are conscious of all the issue connected with browsers and
their problems, you can build a good system that is able to protect not only
the security of the users but also their privacy. And the privacy can not be
protected with a server-based cryptography system.

------
jwatte
I think using TLS is largely the right solution, and "shouldn't be hard" (a
$400 certificate is the hardest bit). However, the article assumes that modify
attacks are as simple as intercepted, which I do not believe is true. It's not
about GUIs. Re-routing DNS requires holes and access that a properly
configured infrastructure won't give you. However, as long as you can put up a
competing DHCP server at an open Starbucks network, you can probably own
anything non-TLS.

------
swah
Would be cool if this had an author listed.

~~~
tptacek
Hi.

------
donpark
While I agree with most of the issues raised in the article, I disagree with
the blanket conclusion. With HTTPS, JS crypto can add to security when applied
appropriately.

In particular, requiring hacker to compromise not only the server but also
each client adds to security and limits damage footprint, much more so if
combined with external blackbox-style monitoring of served contents and
scripts to catch server-side compromise timely.

~~~
marshray
The clients don't need to be hacked, they simply run code as instructed by the
server using standard, documented interfaces. Once the server is compromised,
or any other party that can serve non-image content into the page origin, it's
game over.

~~~
donpark
I didn't mean client has to be hacked but did mean script from compromised
server has to run on client to decrypt user data. Hacker has to compromise the
server then, for each connecting user, serve malware javascript.

Meanwhile, external network of monitors, masquerading as real users, detect
that server is compromised and alert the admins who can take appropriate
actions. Overall, compromised server can be shut down in minutes during which
only a fraction of user base will have been affected.

How does this _not_ add to security?

~~~
marshray
_Hacker has to compromise the server_

Or the connection in between, unless SSL is satisfying that part of our threat
model.

 _then, for each connecting user, serve malware javascript._

No problem there, that's a core function of a server. It's a feature of MitM
tools as well.

What's more difficult is an attacker who wants to target only a few specific
users.

 _Meanwhile, external network of monitors, masquerading as real users,_

A nice idea, let me know when you get that implemented.

 _detect that server is compromised and alert the admins who can take
appropriate actions._

That's always a fun conversation to have. Be prepared for denial, anger,
bargaining, and depression before getting to acceptance.

Monitor network: "We've found sometimes users are receiving the old version of
the Javascript, you know, the buggy one? Particularly when certain key words
like 'democracy' occur in the text."

Site operator: "Oh, must be an old file on one of the servers."

Monitor network: "We think it might be a targeted attack"

Site operator: "Well, what are the _chances_ of that"

Monitor network: "This is not a random phenomenon like earthquakes"

Site operator: "But, you can't _prove_ it, and not _all_ users are affected,
right?"

...and so on

 _Overall, compromised server can be shut down in minutes during which only a
fraction of user base will have been affected._

This scheme should not be confused with actual security.

 _How does this not add to security?_

More moving parts to break and make things worse. Every bit of script and
supplemental page content is another weakest link.

And they will break, because they're being developed by those who are ether
don't understand or are not willing to admit that they're pushing snake oil,
even after the systemic flaws in their scheme have been pointed out
repeatedly.

~~~
donpark
> Or the connection in between, unless SSL is satisfying that part of our
> threat model.

From my original comment: "With HTTPS."

> A nice idea, let me know when you get that implemented.

It's part of a service I'm currently previewing privately.

One of the projects I worked on was a sophisticated fraud-detection framework
which was deployed to one of the largest banks and acquired by a top security
company. Stuff like this is not easy to implement and work never ends but then
that's why we get paid.

~~~
marshray
I could see it working well enough for banks. But banks are an unusual
scenario. They (and maybe insurance companies) are the only businesses that
have become accustomed to having so much loss due to fraud that they can
handle it as aggregate risk and a cost of business.

------
crdoconnor
While largely true, there is still scope for client side javascript encryption
for applications where the service provider largely just wants to prove to
some external agency (e.g. the government, or some court issuing a subpoena)
that they _can't_ have access to your data.

~~~
marshray
That'd be a hard thing to prove considering the service provider (and every
other party serving non-image content into the page origin) could access the
data any time they wanted by simply sending some script.

------
tzs
So are there situations where it is reasonable to do JavaScript cryptography?

Here's a hypothetical: you have producers and consumers of certain documents.
You want a system where a producer can produce a document for a particular
consumer, put it on a server, and that consumer (and only that consumer) can
retrieve the document and read it. Ideally, you want to this as unobtrusively
as possible from the point of view of the consumer. If the server is
compromised, the intruder should not be able to read any of the documents.
It's hypothetical, but something I once worked one would have benefited from
such a system, so I spent some time considering how it could be designed.

One approach would be to have a public/private key pair for each consumer.
When a producer prepares a document for the user, it is uploaded encrypted
using that consumer's public key. The encryption would be done on the
producer's client machines (producers are on a company LAN using computers
administered by a competent IT department, and can be assumed free of
malware).

On the consumer side, we need to solve three problems: (1) generation of the
public/private key, (2) storage of the private key, (3) decrypting downloaded
documents.

One approach to this would be to tell the clients to install PGP, generate
keys, and send the public key to the producers. Clients could then download
documents via their browser, and run PGP to decrypt them. That fails the
"unobtrusive to the client" requirement.

So let's consider the JavaScript approach. The JavaScript can be delivered
over SSL, with all elements of the page coming over SSL from the same server
(which could be separate from the document storage server).

For generation of the public/private key, the lack of a secure random number
generator in JavaScript would seem a hindrance, but is it? Couldn't a CSPRNG
be used in JavaScript, seeded with something derived from the user's password?
That would have entropy limited by the entropy in the user's password--but how
is that different from using a secure random number generator but then storing
the private key encrypted with the password? In either case the difficulty of
getting the private key for an attacker is limited by the entropy of the
password.

If the private key is generated as above, it can be regenerated from the
password as needed so there is no need for key storage.

It seems to me that the above sidesteps most of the issues raised in the
article that are specific to JavaScript. The ones that remain, where someone
has compromised the client machine via another route, would also apply to a
client implementation done as a stand-alone application. If the client machine
is compromised, the client's documents are vulnerable.

Let me also propose one more scenario. What about JavaScript that is NOT
delivered over the net on each use? For example, suppose (still using the
hypothetical producer/consumer example) that when a consumer signs up for the
service, the sign up server generated the public/private keys, then
dynamically created a static page with embedded JavaScript that includes the
private key (encrypted with the consumer's password) as data. This static page
is bundled up with any other resources it needs (images, style sheets) into a
zip file, and that is given to the client.

The client unzips this, and when he wants to get documents launches the static
page in his browser. The static page references its resources by file:// URLs.
Essentially it is an application that happens to use the browser as an
execution environment. The network is only used to make an AJAX call to get
encrypted documents from the server.

~~~
saurik
""That would have entropy limited by the entropy in the user's password--but
how is that different from using a secure random number generator but then
storing the private key encrypted with the password? In either case the
difficulty of getting the private key for an attacker is limited by the
entropy of the password.""

Because you just removed the requirement of the attacker to steal (or at least
compromise) the laptop, to get access to the encrypted key: the entropy of the
_key_ was still high, it was simply protected on the laptop with a weak
password; that's very different from deleting the key and forcibly reducing
its entropy to that of the password.

------
mcantelon
"___ Considered Harmful" considered harmful.

------
cybernytrix
bit.ly/ndt4ss What does it take to get some attention on HN? Do you have to be
part of some secret cabal? I solved all the problems he talks about (and I
worked with a crypto guy):

\- Statically encrypt and publish content on HTTP server \- Transmit these via
HTTP to an iframe component at client browser \- HTTP-iframe locally sends
message to HTTPS-iframe via window.postMessage() \- HTTPS-iframe decrypts
content (with pre-shared key) and renders it on page

I implemented a library to do this (3 years ago!). Anyone care to tell me just
ONE vulnerability with this? Thanks! bit.ly/ndt4ss

~~~
marshray
The unencrypted (or more importantly, unauthenticated) content loading into
the iframe is subject to any number of malicious content injection techniques.
E.g. [http://www.thespanner.co.uk/2007/10/24/iframes-security-
summ...](http://www.thespanner.co.uk/2007/10/24/iframes-security-summary/)

Professional malware distributors seem perfectly happy to obtain placement
inside an iframe:
[http://www.usenix.org/event/hotbots07/tech/full_papers/provo...](http://www.usenix.org/event/hotbots07/tech/full_papers/provos/provos.pdf)

Edit: Also, don't you trigger mixed content warnings in the browser?

------
thinner
FTA:"THAT ATTACK SOUNDS COMPLICATED! SURELY, YOU'RE BETTER OFF WITH CRYPTO
THAN WITHOUT IT? There are three misconceptions embedded in that common
objection, all of them grave..."

I guess I shouldn't lock my car, either, right? After all, someone could
simply break my windows and steal whatever I have inside. Or maybe, just
maybe, using some protection actually _is_ better than using no protection,
provided you don't put more faith in the protection than the protection
warrants. Just like I wouldn't store gold bars in my car, I wouldn't use
jscrypto to protect things that were too important for that level of
protection. I will, however, feel okay about keeping my sunglasses in my car,
and I will feel okay about using jscrypto to send my phone number over email.

~~~
marshray
I'm glad you mentioned this because I feel it's worth a response.

When you develop protocol or infrastructure code the _more general_ the
facility is that you develop the _less_ control you have over how the result
is going to be used.

For example SSL was originally developed for the purpose of making people feel
safe transmitting their credit card numbers to e-commerce websites. Credit
cards (like cars) have a pretty predictable upper bound on the financial loss
should this system break.

However, the SSL/TLS protocol was very general and it has grown to be used for
everything under the sun today. From protecting Twitter APIs to "launch the
missiles"-type critical systems.

So when you advocate a general technique like Javascript browser crypto, you
don't get to qualify it with "only for stuff that really isn't worth attacking
anyway". You don't know in advance what data it's going to be used for, much
less what the value of that data will be to attackers in the future.

------
hammerdr
From the article:

"Any attacker who could swipe an unencrypted secret can, with almost total
certainty, intercept and alter a web request. Intercepting requests does not
require advanced computer science. Once an attacker controls the web requests,
the work needed to fatally wound crypto code is trivial: the attacker need
only inject another <SCRIPT> tag to steal secrets before they're encrypted."

This is strictly true from the perspective of cryptography. Crypto is always
concerned with the strength of crypto from a mathematics point of view.

However, much of that worldview falls down in the real world. In the case of
hashing a password before it goes over the wire (even the simplest salt-free
MD5), which is crypto-logically naive and "considered harmful," you are
providing a general barrier for people that are FireSheeping in a cafe. Many
would-be attackers are thwarted by what crypto-nerds would see as silly.

In general, the weakest point of crypto in today's world is the human element.
RSA Security got hacked not because the algorithm was weak but because someone
installed a back door in RSA's network for the hackers. Once you get passed
the point where it is more effective to attack sideways than head-on, the
crypto has done all it can do.

That being said.. just use SSL. It moves that gauge enough that anyone trying
to get your users' information isn't going to bother direct attacks.

Edit:

What I meant by the 'salt-free' MD5 is that of a challenge-handshake response.
The challenge is sent by the server and the client responds with
md5(pw+challenge). The salt would otherwise need to be sent in an insecure
manner that would provide only marginal more security than a challenge-
handshake. This was unclear and I apologize.

~~~
dchest
What barrier? If you're sending password hash over the wire, and the server
allows access based on this hash, the hash is essentially the password.
Firesheep, BTW, steals cookies, not passwords.

