Hacker News new | past | comments | ask | show | jobs | submit login
Cryptography and how to deal with man-in-the-middle attacks in JavaScript (sessionstack.com)
71 points by zlatkov 13 days ago | hide | past | favorite | 58 comments





This article is silly and i would argue dangerous.

One of the applications they suggested is MFA. If you're validating mfa on the client side you are doing it wrong.

They give 3 ways to deal with MITM attack. PKI isn't mentioned as one of them. Who the hell tries to deal with MITM by looking at network timings?

There's a reason that the api has subtle in the name, its because using it naively will shoot yourself in the foot. Unless you have a very specific usecase,leave the crypto to the tls layer.


> One of the applications they suggested is MFA. If you're validating mfa on the client side you are doing it wrong.

Agreed.

> Unless you have a very specific usecase,leave the crypto to the tls layer.

Agreed.

Author should delete that blog post. Normally, I wouldn't suggest that, but since this is dealing with security, it should thoroughly scrutinized, especially since there are so many JS noobs just starting their careers and they might look at this post as best practices.


The main issue I still see with JavaScript crypto in a Website session is how you can verify the Code running in the Browser isn’t tempered with.

I got no issues with it inside a browser extension, because a Website cannot change the Code running there, correct?

What I mean is, an advertisement could simply override the crypto API and do whatever it wants with it.


You generally wouldn't put adverts on a site that's dealing with security.

You should also add subresource integrity as a defence in depth. https://developer.mozilla.org/en-US/docs/Web/Security/Subres...


I know you or I or someone on HN talking about secure environments wouldn't put adverts on a site. But I just checked the first thing I could think of (https://www.coinbase.com/signin) and I can see Google Ads right there. I don't want to sound like I'm calling them out specifically because I'm sure what I'm looking at is entirely normal.

It unfortunately apply also to many banks, airlines etc. All the conversion tracking, retention, ads, various third party sdk etc.etc. has full access to user information.

Yes, I just looked at the source. That leaves them open to an attack, but I guess they trust google. Fingers crossed.

There’s many security sites that load tons of external scripts. My bank is one such example. Even if those third party trackers and such are trustworthy there remains the whole supply chain attack consideration.

Banks are never a good example for security. I know mine, which is a big name, still doesn't support OTP 2FA.

Banks, Enterprise management, ... these are all guarding extremely valuable assets so i considered them security websites (not sure what is more security relevant other than the master email account we all have). They are written in a way that is hard to secure through CSP, disabling javascript, etc.

Oh, that looks cool.

You verify it with TLS.

But then that raises the question of why you need crypto if everything is already encrypted and verified via TLS.

There are probably a couple obscure unique usecases (maybe if you're doing some p2p stuff with webrtc), but i'm pretty convinced client side crypto on the web is useless 99% of the time.


> But then that raises the question of why you need crypto if everything is already encrypted and verified via TLS.

Depends where the TLS path terminates and what your threat model is. If I send a message via a service (an email via gmail.com for instance) the message is only protected by TLS as far as that provider. If the content itself is encrypted as well as the transport (and that provider does not know the keys) then the message is still protected at that point. This could be important for code sending data via an API proxy of some sort.

Also remember that the user of the browser might not have control over what certificates are trusted for HTTPS purposes. If they are operating in an environment where a local CA certificate is installed and that is used by a transparent proxy to enable them to inspect otherwise secure streams, the application protecting the content as well as the transport may protect against that (though you'll be wanting to use PKI here - otherwise you have a key distribution problem).


Client side encryption is still useful for webapps (or even proprietary apps) for example in apps like protonmail. At any time the company could send a payload that would extract the keys and pwn a user. But what it does provide is the guarantee that if they start non malicious, but later become malicious the scope of their capabilities are limited. If you don't log in to some historical account there is nothing they can do the attack has to be active. Similarly continuing on the example plaintext emails are encrypted when they are received by them and stored with your key. You could argue "well they could just not encrypt them". But any emails that they did encrypt while not malicious are still outside of their power if they change.

Bitwarden, and all web based password manager clients, rely on client side crypto for ensuring the data is not viewable by the service provider.

I'd argue that I would like to see more client-side crypto. I'd prefer my data to be stored encrypted and inaccessible to third parties such as Google. Google Drive or Dropbox would get my business back instantly if they supported client-side encryption of data. Of course, in Google's case, that would completely break the business model of mining us for every ounce of data.


Imagine a world where the (signed) DNS response contains a root hash of the contents of the page you are visiting.

If the page is dynamic, not everything can be linked into that hash, but paired with CSP you can 100% guarantee that any code that executes is coming from a trusted source.

Then there's technologies like DNSLink for IPFS that obviate the need for this altogether, since the DNS response just contains the hash of what you want, and you ask IPFS for that hash, and anyone who's got it can deliver it to you.

https://docs.ipfs.io/concepts/dnslink/


If the attacker can replace the code inside your web application, then you have security issues somewhere else than in your application.

I forgot which state does it, but there is at least one which intercepts all web traffic and runs it through MitM Proxy’s. I believe it’s citizen are forced to install their root certificate too.

Maybe you're thinking of Kazakhstan. Important to note that citizens had to install a root certificate for this to succeed, and even Then major browser vendors took action to invalidate it.

https://en.wikipedia.org/wiki/Kazakhstan_man-in-the-middle_a...


All other browsers have inferior trust store.

Kazakhstan was it I think

one of my big issue of placing google analytics or some kind of font js on your web site!

Nice overview of the crypto.subtle apis, but I'm not sure about some of the use cases.

>Multi-factor Authentication >Sometimes, hackers can steal users’ passwords. So, even if these passwords are hashed or encrypted in the database, it can’t stop them from accessing a user’s account. To make sure that someone who’s accessing an account is the true owner, applications allow multi-factor authentication. >Rather than using transport-layer authentication, such as TLS client certificates application can use suitable client keys which may have been previously generated via the user agent like multifactor tokens.

I could not follow this part. With FIDO, you have should have a Trusted Platform Module or Hardware Security Key to store the secret key, but I'm not sure what is being suggested here.

In the section on "How to deal with man in the middle attacks", there is no mention of TLS 1.3, which would be the #1 thing on my list.

I agree with others here, that JS Crypto is shaky because you still need to trust the server not to give you compromised JavaScript. TLS and the Same Origin Policy are designed to sort of bridge the security boundary of the server up into your browser page. In this scenario, just offload the crypto to the server.


I would be hesitant to trust any cryptographic implementation coming from browser JavaScript. It’s not that I doubt or don’t trust the implementations from the browser vendors. I don’t trust the JavaScript developers executing them. This will provide a false sense of security implemented by persons lacking the education, training, and experience in security.

Most software developers generally are not formally trained in security as a separate domain of knowledge. If you think security is something that can be passively acquired by reading a few APIs you are wrong. This is why employers require certifications for security work that software development otherwise doesn’t require.

Cryptography was one of the most challenging domains/chapters in preparation for the CISSP. This is because real world cryptography implementations comprise various different cryptographic functions doing different things, such as: certificates, encryption, signatures, hashing, and so forth. The different crypto functions serve different purposes because they have different pros and cons. There isn’t some encryption blanket solution.


Can you recommend resources to learn security? Passed 3 security modules at my university and it feels like I know not much about secure engineering.

Study first for the Security+ exam. That is the entry level security certification. It is much harder now than it used to be. You can find a lot of books and study material about it online.

The gold standard is still CISSP for the corporate world. It is more of a managerial standard. The best study guide is the official course book: https://www.amazon.com/Certified-Information-Security-Profes...

https://en.m.wikipedia.org/wiki/Certified_Information_System...

The standard most prized by government and security researchers is GIAC from Sans.

https://en.m.wikipedia.org/wiki/Global_Information_Assurance...

To take the CISSP you have to apply for the exam because there are prerequisite criteria and the exam costs $700. Even still it only has around a 60% pass rate. The GIAC tests are supposed to be much harder and are extremely expensive. I passed the CISSP but have never taken any of the GIAC tests.


They asked for learning resources, not paid certifications most of us ignore on CVs.

That’s because you are a developer and not a security manager.


CISSP has a somewhat positive reputation, but lots of the other certs are basically negative signal on a resume.

There's lots of different types of security stuff. If you're interested in the more risk management corporate side, looking at study material for certs like CISSP can be useful (but use it as a starting point of things to learn, dont follow blindly). If you want to learn crypto, that's not the path i would reccomend.


The software industry does not value certifications... at all.

The networking and security industries, on the other hand, require them. Attaining those jobs/skills from the perspective of writing software is the surest way to waste your time and accomplish nothing.


The ask was "secure engineering", yeah? The auditors and pentesters we hire have never presented me with their certificates ¯\_(ツ)_/¯

> That’s because you are a developer and not a security manager

These days, I'm neither.. but I am a founder in a security-critical space.


For CISSP specifically, search for anything by "Shon Harris"

Here are a collection of links that I have, YMMV (theres probably a some overlap in these links): https://www.youtube.com/playlist?list=PLOM5uDrM2ZKt0ndd-bOYE... https://simonowens157.gitlab.io/cissp/ https://www.youtube.com/watch?v=JWqd_qaR81g&list=PLEiEAq2VkU... https://github.com/ericagleaton/CISSP-2 https://github.com/gatlindada/cissp-mind-map https://github.com/TheRealBenForce/cissp-mnemonics https://www.youtube.com/playlist?list=PLIVIIjsKiaM8Gtb4oJYqJ... https://www.youtube.com/playlist?list=PL8qqAEgqfCHCKNn92SLeE... https://www.youtube.com/playlist?list=PLX1YKQDEsO8B8bevQuTZH...

If you have access to linkedin learning, there are a number of decent resources there also.

EDIT: unrelated to ^, Checkout youtuber "Ippsec" - he does hack the box challenges (retired boxes).


EDIT 2: This is also really great, very recent talk. https://www.youtube.com/watch?v=v1Qt_YYtBoM

Speakers Site and slides used for ^ https://momjian.us/main/writings/crypto.pdf

For those who dont want to click on PDF (Good stuff) link to site: https://momjian.us/main/ Bruce Momjian is a legend.


"Security" is a broad concept encompassing many things. You might want to figure out what you want to learn.

If you want to learn more about crypto, there's various books (not sure how up to date , but https://www.goodreads.com/book/show/7602360-cryptography-eng... is a good introduction) https://cryptopals.com/ is also good if you like hands on.


For cryptographic primitives, some of the theory behind them, their practical use and what can go wrong when you fuck things up, 'Serious Cryptography' (https://nostarch.com/seriouscrypto) is a good book.

Interesting article. The built-in crypto module was new to me. This is actually a web standard:

W3C: https://www.w3.org/TR/WebCryptoAPI/#Crypto-attribute-subtle

Mozilla docs: https://developer.mozilla.org/en-US/docs/Web/API/Crypto/subt...


That's right. SubtleCrypto implementations are also fast, and available on mobile browsers. SubtleCrypto has some design choices to avoid common mistakes to reduce risk of vulnerable implementations[1], and as such it's aimed at the general developer.

In my opinion, more developers should familiarize themselves with the tools and start looking at how they could implement security for their users.

Processing highly critical data, such as PII or financial data, is not a requirement to use cryptography. Starting out, on could well be served by trying it in personal projects or even public data. This way, uncovering a vulnerable design could mean uncovering data that was already meant to be seen.

Some will always argue it's the wrong or the dangerous thing to do, and they will never ship security to their users, I guess.

[1]: For example, the ReactDOM manipulations breaks this security model because SubtleCrypto will only interface with the DOM. There are additional libs as workarounds for these issues tho.


> and as such it's aimed at the general developer.

Its literally named subtle to discourage the general developer.

In the https web model, there are very few situations where using this api actually makes sense. (Seriously, i challenge you to name one in a typical server-client web app)


> Its literally named subtle to discourage the general developer.

“It is named SubtleCrypto to reflect the fact that many of these algorithms have subtle usage requirements in order to provide the required algorithmic security guarantees.”[1]

This was the closest to an explicit mention of the name I could find right now. It could read both as ‘the api provide security guarantees’ or ‘the developer provides security guarantees’. The article goes on to mention the customary warnings for developers about to do dangerous things.

So yes, I believe you are right on this one. My memory served me otherwise. I still think developers would do themselves and their users a service by learning about applied cryptography and how to securely implement it.

> In the https web model, there are very few situations where using this api actually makes sense. (Seriously, i challenge you to name one in a typical server-client web app)

There are no situations where using this api without HTTPS is even possible. SubtleCrypto is only available in secure context. Making an argument that the api then doesn't make sense in said secure context doesn't resonate with the design choices behind it.

About server-client apps, client-side cryptographic schemes are a thing. I access my encrypted cloud storage provider right now which implements client-side crypto. So are end-to-end cryptography, e.g. two users messaging each other througn a common server. These use-cases are not covered by HTTPS as we know.

Here's a link to some part of Matrix[2] that seem to use this api, but don't take my word for it.

[1]: https://www.w3.org/TR/WebCryptoAPI/#subtlecrypto-interface

[2]: https://matrix-org.github.io/matrix-js-sdk/8.1.0/crypto_aes....


Yeah it is what spawned these wire proton mail guys to encrypt on the client side.

The irony is when running their product on your site you are opening yourself up to an MITM attack from them. https://docs.sessionstack.com/docs

To be fair most SAAS javascript products (google analytics, stripe payments, etc) are going to work like this and they also offer an on-premise solution that presumably doesn't have this issue.


As long as server can serve any JS to any client, you can’t protect the data from the server.

It’s more complicated than that. For the most part the browser is a secure environment due to same origin policy. JavaScript in the browser can only send and receive from the domain from which that JavaScript is served, which means the JavaScript must come from your own domain or from a third party you trust. That trust is all from the perspective of the web server, though, which is orthogonal to the concerns of the end user.

https://en.m.wikipedia.org/wiki/Same-origin_policy

Browser extensions can bypass that though, which can expose you to malicious third parties.


"Third party you trust" is tricky though. Like what happened with Backblaze. I don't think they really intended to scarf private data and exfiltrate it. Probably just a marketing person not knowing the implications. https://news.ycombinator.com/item?id=26536019

How is that? Lots of sites server their code to any client, but the data contained within the service is still secure.

'Javascript crypgography considered harmful' by tptacek (2011): https://archive.is/cyk2R

tl;dr: In most cases browser JS crypto offers no advantages if you're trying to protect yourself from a rogue/compromised backend (eg. do e2e crypto on keys stored within localstorage before passing that over to the backend). That is because if the backend is compromised it can likely serve backdoored JS code that will leak secrets.

This is not always true (eg. if you have multiple tiers of server backends within separate security domains), but almost always true for typical web monoliths.


The article doesn't really explain the reason that MITM attacks are possible and how to prevent them in the first place. That is too bad because that part is pretty much at the end of the article.

What year is it? 1990?

Quote: "As people communicate over the internet, there’s a possibility that others can eavesdrop or even hijack information before it gets to the other parties involved."

Let me tell you something buddy, if someone can decrypt->modify->encrypt undetected your communications then JavaScript is the least of your worries.


Core mechanisms to prevent Man-in-the-Middle are missing in the article: PublicKey/certificate-Pinning or PKIs. Cryptography is best left to the experts, most of todays javascript developers are probably missing the knowledge to implement or use it in a correct way

Those are browser features, not JavaScript features. This is an article about JavaScript.

No, those are crypto concepts.

You can implement them in javascript or any other language you choose. (Doing so in client side js is probably a stupid idea, but so is pretty much everything in the article. Its definitely possible though)


Can you explain to me how you think certificate pinning would work in JavaScript? That doesn't make any sense.

Client-side crypto (even in JavaScript) has its place, but certificate pinning is specifically a TLS thing, and IMO not relevant to this discussion.


You have funcs to make public/private key pairs. Funcs to sign things. You can make your own PKI in the usual manner. You could then pin on specific keys in your chain of signatures if you want.

Why you would, i dont know. Its a terrible idea like most use cases for js client side crypto, but you could if you wanted to. Then again, cert pinning is a mostly terrible idea in the context of TLS too.


Sigh. Everybody in software believes they have some variable understanding of security but in most cases that confidence isn’t validated by anything. In most cases developers talking about security is Dunning-Kruger on full display.

Essentially every software security related subject can be qualified by a single question: What industry trusted process validates your concern?


Interesting article. Thanks For Sharing

Just a sec, need to put on my tin foil hat...

It looks like this post is from a person in Nigeria. Perhaps this is a scam where they create a blog post targeting JS noobs where they advocate for questionable security practices, making web security a little more vulnerable, therefore making it easier for scammers to exploit client side JS.

If that's the case - bravo, that is some jedi level mind tricking.

Obviously, that is unlikely, but would funny if even remotely true.

EDIT - I take that back, looks like this is the blog of a legit company [1], though it looks Russian hmmmm

[1] https://www.sessionstack.com/about


Why did you jump to that conclusion? The only explanation i can find would be to brand you as a racist, but i'd rather not, that is why i am asking.



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

Search: