Hacker News new | past | comments | ask | show | jobs | submit login

> Seriously? It makes it more difficult to get things right, but the risk of getting it wrong is not increased? And that after you just described how the challenges of JS have already directly led to vulnerabilities?

Well it seems that you misunderstood which challenges I was talking about. Lack of types is a big problem, but besides that everything else doesn't make the risk bigger.

> How exactly does a malicious server not affect "crypto browser apps"?

I didn't claim that malicious servers won't be able to affect crypto browser apps. What I said is that in these apps you have to trust the server already, so it doesn't make sense to consider them untrusted.

> How does staying out of scope for PCI DSS have anything to do with security (except maybe demonstrating that PCI DSS is crap because it can so easily be circumvented)?

It's exactly the point. When people say "javavascript crypto is harmful" they don't consider use cases where it's really useful, even just to circumvent PCI DSS.

> Also, in what kind of scenario would leaking info in a referer be a problem, but leaking the same info in encrypted form would not?

I don't understand this question.

> And how do you guarantee that your verification code is loaded fresh from the server once your application has been compromised in a browser?

Because every time I refresh my browser I get a chance to get some trusted code from the server.




> Well it seems that you misunderstood which challenges I was talking about. Lack of types is a big problem, but besides that everything else doesn't make the risk bigger.

So, it isn't actually a bit more challenging then?

Also, it seems to me like you are at least forgetting timing and possibly other side channels.

> I don't understand this question.

I just can't see any actual scenario where that helps, mostly because it seems to me that the cipher text usually would be a plain-text equivalent, so it doesn't really matter to the attacker whether they have the plain text or the cipher text.

> Because every time I refresh my browser I get a chance to get some trusted code from the server.

So, in other words, you don't have a guarantee?

Other than that, and in general, it seems to me that your argument is somewhat of an equivocation fallacy: You are essentially redefining crypto to include kinda-non-crypto, to then claim that this redefined crypto actually can sensibly be used in browser-side JS, and therefore the arguments against the use of the original crypto are somehow not good advice.

I would think that it is rather obviously implied in most criticism of JS crypto that you are not just executing code that performs a cryptographic primitive, but that you are actually using it to achieve some security goal, and in particular that you are using client-side JS rather than some server-side crypto for some security advantage. That is essentially the implied vague threat model.

So, yeah, it's true that there are uses for crypto primitives that aren't affected by that threat model, because they aren't about security at all. And others that are less affected for various reasons. But it's highly misleading to therefore claim that "most applications aren't affected by that threat model". I'd think that most applications actually are. Except for those built by people who do understand enough of cryptography to not need posts such as the one by matasano. That is to say: Yes, once you yourself can write such an FAQ, you might be able to make use of JS crypto. But at that point, that post won't keep you from doing it anyhow. If you can't, though, chances are you first need to understand every single point made in it.


> So, it isn't actually a bit more challenging then?

More challenging, yes. Riskier, no.

I don't like that Javascript doesn't have native support for big integers (like Python does), or that it stores numbers as floating points in a 52-bit mantissa, but I fail to see why this makes developing crypto code riskier.

> Also, it seems to me like you are at least forgetting timing and possibly other side channels.

Well, I ain't. When you don't control the instructions being executed by the CPU you may have the risks of security-sensitive information leaks. This applies not only to Javascript, but also to all scripting languages. I could say that it also applies to Java, if the methods in its BigInteger class aren't fixed-timing.

In other words using Javascript doesn't make the problem any worse. If you disagree, you're invited to take a look at End-To-End, find a side-channel leak and write an exploit for it. You could earn serious cold cash with that finding.

> I just can't see any actual scenario where that helps, mostly because it seems to me that the cipher text usually would be a plain-text equivalent, so it doesn't really matter to the attacker whether they have the plain text or the cipher text.

I described where it helps in my article.

Re your last point: if doing SSH in a browser isn't crypto I don't know what could be. Is the only thing you consider Javascript crypto encrypted webmail? That's your problem then. You know one wrong use case, and you refuse to admit that there are other legitimate ones.

Edit: remove a few unnecessary sentences.

Edit: some people don't like Javascript crypto so much that they downvote me without saying anything.


> More challenging, yes. Riskier, no.

Please explain. Is it that it is more challenging, but in a way that it's not more difficult to get it right (what exactly is the challenge then?) or is it not riskier because the higher probability of getting it wrong does not decrease the probability of getting it right (how exactly do you increase one probability without decreasing the probability of the negated case?)?

> This applies not only to Javascript, but also to all scripting languages.

So, a bridge built from matches isn't any more robust than a bridge built from toothpicks, therefore building bridges from toothpicks is a good idea (nevermind that other people are using reinforced concrete for bridge construction)? I'm sorry, but I can't quite follow your argument.

> If you disagree, you're invited to take a look at End-To-End, find a side-channel leak and write an exploit for it. You could earn serious cold cash with that finding.

You are not seriously bringing forward the "secure-because-hacking-contest" argument, are you?

> Re your last point: if doing SSH in a browser isn't crypto I don't know what could be.

Sure it is, but it still is rather obviously not what those posts are primarily attacking. Or maybe it is, if anyone claims or implies that this "SSH-client in a browser" is any more secure than "browser frontend to SSH-client on the server". Which I think is kinda the whole reason for its existence? Performance- and complexity-wise, I doubt that it makes any sense at all to implement the SSH protocol itself in the browser in that case, vs. using a native SSH client on the server.


> If you disagree, you're invited to take a look at End-To-End, find a side-channel leak and write an exploit for it. You could earn serious cold cash with that finding.

For one thing, the IDEA implementation seems to be incorrect. In IDEA, multiplication is defined as multiplication modulo 2^16 + 1, where 0 means 2^16 [3]. However, looking at the multiplication function:

https://code.google.com/p/end-to-end/source/browse/javascrip...

When x == 0 but y != 0, the result of the modular multiplication is always 0, when it should not be. The correct code would be (in glorious C syntax, everything unsigned and 32-bit):

    if(x != 0) {
        if(y != 0) {
            return x*y % 65537; // result fits in 32 bits
        }
        else return 65537 - x; // or 1 - x mod 2^16
    } else return 65537 - y; // or 1 - y mod 2^16
Of course, even if correct this code is still vulnerable to timing attacks (under contrived conditions) [1]. This can be worked around using a little bitwise magic:

    t0  = 65537 - x;
    t1  = 65537 - y;
    t2  = x*y % 65537;
    b0  = -(1 ^ ((x | -x) >> 31)); // 0xfff..ff if x == 0
    b1  = -(1 ^ ((y | -y) >> 31)); // 0xfff..ff if y == 0
    return ((t0&~b0&b1) | (t1&b0&~b1) | (t2&~b0&~b1) | (1&b0&b1))&0xFFFF;
Additionally, the modular inversion seems to be needlessly complicated by using Euclid's algorithm (and I'm not sure it's correct either: it seems not to respect the "0 means 2^16" rule). Use the usual a^(p-2) mod p inversion trick, using an optimal addition chain [2], to make it simpler, constant-time, and possibly faster.

None of this is Javascript's fault, for what it's worth. But I certainly don't expect Javascript to make it any easier to write correct code, much by the contrary.

EDIT: Fixed constant-time code.

[1] https://www.schneier.com/paper-side-channel2.pdf

[2] http://wwwhomes.uni-bielefeld.de/cgi-bin/cgiwrap/achim/scrip...

[3] http://www.isiweb.ee.ethz.ch/papers/arch/xlai-mass-inspec-19...


Thanks for the report. I'll take a look and get back to you. Where can I contact you?

Edit: I've just filed https://code.google.com/p/end-to-end/issues/detail?id=82. We can discuss the problems of IDEA there. Thanks!


That link gives me a 403 error? In any case, I've put an email in my HN profile.


Oh yeah, it was restricted to my team. I'll make it public, and notify you via email. BTW IDEA is not enabled/registered.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: