How frequent (and/or sophisticated) are man-in-the-middle attacks?
About
In cryptography, the man-in-the-middle attack (often abbreviated MITM), or bucket-brigade attack, or sometimes Janus attack, is a form of active eavesdropping in which the attacker makes independent connections with the victims and relays messages between them, making them believe that they are talking directly to each other over a private connection, when in fact the entire conversation is controlled by the attacker. The attacker must be able to intercept all messages going between the two victims and inject new ones, which is straightforward in many circumstances (for example, an attacker within reception range of an unencrypted Wi-Fi wireless access point, can insert himself as a man-in-the-middle).
http://en.wikipedia.org/wiki/Man-in-the-middle_attack
The reason I ask is to try and gauge whether it's worth the added overhead of encrypting important sections of the content I'm sending to the user or whether it's safe to just go ahead and send it unencrypted.
Note: I know this isn't strictly a "programming" question insofar as there is no code solution, however it influences coding decisions and is coding-based, so it still seems appropriate.
It doesn't take a MITM attack to read data that hasn't been encrypted at all. A MITM attack is used to allow an attacker to read data that has been encrypted.
Edit: The relevant question with respect to MITM attacks is not whether you should do encryption at all. It's whether you should do some sort of authentication (i.e., verifying the identity of the remote party) while you set up an encrypted connection.
With no encryption at all, a "snooper" just looks at your data as it goes through, and sees exactly what's there. A MITM attack applies when you do encryption, but don't verify who you're sending the encrypted data to. In this case, the attacker inserts himself in the middle of the conversation -- you connect to the attacker, and send him encrypted data. He connects to the person you intended to talk to, and creates an encrypted connection to both of you. Then, as you send your data, he receives it, decrypts it with your key, re-encrypts it with the target's key, and sends it to the target. Likewise, any returned data he decrypts with the target's key, and re-encrypts with yours.
This way, it looks to both you and the target as if the communication is going normally -- but the attacker can read everything you send. If you don't encrypt the data at all, though, none of this is necessary -- since you're sending plain text, the attacker can just look at it as it goes by.
The MITM attack is not necessarily thwarted by encryption. For example, if you encrypt using a so-called "self-signed certificate," then your communications will be encrypted, and yet a MITM attack could still occur. For example, with a self-signed cert, if you load "Fiddler" onto the client box, it will perform a MITM exercise so that it can watch all the traffic. The client and the server will not realize that the MITM is happening.
If you use real PKI (a true trusted 3rd party is involved), then MITM isn't possible.
In any case, MITM is fairly easy to achieve, if the value of your data is "worth it" to the attacker.
Depends on the application, but if the data being sent is at all sensitive, definitely guard against man in the middle! It is a very relevant danger especially with rise of Wi-Fi, and very easy to do; a friend and I were able to replicate the Gmail MIMA last year with little difficulty.
I would refer you to the Internet Storm Center (isc.sans.org) for any questions about frequency of attack types on the Internet.
Keep in mind that MITM is a very broad term, and you seem to be more worried specifically with just session sniffing (i.e., eavesdropping) attacks. Sniffing attacks are trivial to perform. A full MITM facilitates modification of the session, which can have different implications than simply viewing the information. This modification requires a bit more sophistication, but not custom tools.
Using TLS/SSL on your site will provide protection of the data from prying eyes and ensure that clients are indeed communicating with the correct server.
To address the note on coding - whether you decide to use cryptography or not, you should be engineering your web app such that it would not be onerous to add crypto later.
Any time you talk about security, it's always in context of sensitivity of your data. The more valuable your secret is to someone, the more determined they will be to obtain it, and the more resources they'll expand. Conversely, the more valuable it is to you to keep it secret, the more resources you should expand protecting it.
Man in the middle attacks are pretty accessible to anyone, especially on public networks. It's up to you to decide if you want anyone to be able to read your data or not...
Related
My temmate proposed me to encrypt login/password before sending them to backend.
We use https so I don't see any reason why I should do it and in what circumstances.
Https itself, by definition, is all about encrypting data and protecting us from "man in the middle" attack.
As for me it is not the reason when someone say that we should protect our client from viruses and sniffers, which he has on its computer, and which can decrypt SSL traffic using kindof RSA algorithms. It is up to the owner of the computer. Antiviruses can cope with that pretty well.
One reason when it could be applied is when we store such data on browsers/client's side (for example in local storage), and I think it is architectural risks. All data should be persisted on backend side and browser should be stateless in a way.
Question: in what cases, if any, we do need to encrypt our data before transferring them over https?
Thanks in advance!
You should apply protection to assets (data in this case) when you want to protect it against something. It makes sense to encrypt if you have a threat in mind, a usecase where this data would be compromised, which is prevented by the proposed encryption.
By default, it's a standard and accepted thing to send usernames and passwords without further encryption over https. If you can come up with ways why that's not enough for you in your specific case, you may apply further encryption. For example you might want to protect it against man-in-the-middle attackers, say a corporate proxy that has its root cert installed on clients (very common in corporate settings).
Note though that encrypting it is not straightforward at all, key management is relatively difficult. How will the client have the key, how will it store it, how will you revoke it if compromised, and so on.
Usually it's not worth it to go down this route. In some very specific cases, it might be.
I am creating a chat service program that follows the server/client paradigm. That chat program exists as both a chat server and a chat client, and a user can either host the chatroom(and it will connect his client to that server), or he can join an existing one.
Clients connect via a direct IP address that the other user will tell them, such as gained from whatismyip.com, and a specified port number.
During any time in this chat program, one user can send a file to another user. This is initiated by asking the server to set up a handshake between the two users, with user A passing his IP through the server to user B, and user B calling the new service that user A created for file transfer. This eliminates the original chat server, and the users are connected via a direct IP using nettcp protocol.
Over this file transfer, the files are encrypted with AES after initially sending the AES private key via RSA encryption.
I want to know what kind of ways somebody can initiate a man in the middle attack here. Obviously I see the flaw I have in passing the IP address through the server to the other user, but right now I don't see any other way as I cannot have the server retrieve the IPV4 of the sender.
Is the way a man in the middle attack works, is that he can see that these two users are transferring files, and somehow pull the data stream to himself from both ends? Can he do this on an already ongoing file transfer session?
I'm trying to understand the way MITM attacks work so I can see if I can protect my program from such attacks... but if the only way to reliably do so is to use a certificate authority(of which I'm still learning about), please go ahead and tell me that.
After doing more searching, I found this great link explaining the different types of MITM attacks and how they work and are executed in great detail.
http://www.windowsecurity.com/articles/Understanding-Man-in-the-Middle-Attacks-ARP-Part1.html
There are a total of four parts.
Is the way a man in the middle attack works, is that he can see that
these two users are transferring files, and somehow pull the data
stream to himself from both ends? Can he do this on an already ongoing
file transfer session?
You need to define a threat model. The usual suspects are message insertion, deletion, tampering and reordering. Sometimes the attacker only needs to tamper with a message so you do the wrong thing. For example, he/she may need to flip a bit so "transfer $100 from A to B" changes to "transfer $900 from A to B". In this case, the attacker did not need to be in the middle or decrypt the message.
I'm trying to understand the way MITM attacks work so I can see if I
can protect my program from such attacks... but if the only way to
reliably do so is to use a certificate authority(of which I'm still
learning about), please go ahead and tell me that.
Rather than attempting to design a hardened protocol, perhaps you could use a protocol that already exists that addresses your concerns.
That protocol would be Z-Real-time Transport Protocol (ZRTP). The protocol is specified in RFC 6189, ZRTP: Media Path Key Agreement for Unicast Secure RTP.
ZRTP is a key exchange protocol that includes Short Authentication Strings (SAS) to keep out the MitM. Essentially, the SAS is a voice authentication that only needs to be performed once. You can omit the SAS check, though its not recommended. If you omit the check and the bad guy is not attacking, then everything is OK for current and future sessions.
Once you establish your first secure channel without adversarial tampering, all future sessions will be secure because of the way key agreement for the current session depends on earlier sessions. And the earliest session (first session) is known to be secure.
ZRTP also provides forward secrecy, so a compromise of the current session does not affect security of past sessions.
ZRTP does not require certification authorities or other (un)trusted third parties.
Dr. Matthew Green has a blog about ZRTP on his Cryptography Engineering site at Let's talk about ZRTP.
To answer your question about MitM, there's too much for a Stack Overflow answer. A great free book is Peter Guttman's Engineering Security. MitM is sometimes a goal of an attacker, but it not his/her only vector. Guttman's book looks at a number of threats, how humans act and react, why the attackers succeed, and how to design around many of the problems.
Are there any protocols which would allow 2 visitors to communicate securely through my website, without the possibility of me reading their messages?
Ask Google for End-to-End encryption like PGP/GPG. For a client-side browser-based implementation you might want to check out GPG encryption in JavaScript.
I just googled it and cannot tell if its really secure (not sending your private key to anyone). I just want to give you a point to start with.
EDIT: Looks like it does send the clients private key to your server to perform a server-based encryption. This is not what you want. But I am sure that a JavaScript implementation of GPG is possible even though I don't know if somebody has done it yet.
Yes; for example, this is what would happen if your server was a link in a communication protected by SSL/TLS.
The participants use a public-key encryption scheme to agree upon a secret, symmetric key; that is then used to encrypt their communication.
It's also possible for the participants to simply encrypt their messages with the public key of the intended receiver. That way, only the intended receiver can decrypt the message. This is not a very advanced scheme and probably vulnerable. (Among others, if an eavesdropper can guess exactly what is sent, he can encrypt that message with the intended recipient's public key and see if the result matches with what is being sent).
There is a lot of literature available on cryptographic protocols; for starters, here's a Wikipedia article on Key Agreement Protocols.
If we're talking about not possible then the second part to S.L. Barth's answer will achieve this with the exception that the key exchange must be done by some other means. This can be the phone or email or even another website but if it's done via your website then it's open to a man-in-the-middle attack. You can tell your users to do this, you just can't actually help them do it.
There is probably a javascript library somewhere that will implement GPG encryption so that all you have to do is make sure that every message is encrypted in the browser before it's sent to your web server. You can store the messages as long as you like, they're encrypted. Only the user with the correct private key will be able to decrypt it.
SSL and TLS as they are used by websites everywhere are vulnerable to man-in-the-middle attacks. The reason we don't hear much about these sorts of attacks is that most of the people in the middle are trustworthy so the attacks simply don't happen. The recent revoking of the CA certificates of DigiNotar and others was precisely because the Iranian Government were caught acting as a man-in-the-middle and decrypting their own citizen's SSL traffic.
If you're happy with preventing casual snooping by curious sysadmins, the key exchange can be done through your website as well.
One more thing: Security is hard.
Even if you do this with well-known encryption techniques, the chances of there being a flaw in the implementation will be very close to 1. This doesn't mean that those curious sysadmins will be able to accidentally read messages but it does mean that a determined and skilled adversary will be able to find a way in. As soon as you can afford it you should hire an expert to redesign or at the very least examine your protocol and implementation.
In general, such a secure link between your users without you being able to read and/or modify their messages is only possible if they have some way of identifying each other (or at least in one direction).
This might be a shared secret (like a passphrase) or a public key known to one (or certified by a CA known to one), where the other one has the corresponding private key.
On this one can build a secure protocol (using a key exchange and then symmetric encryption with MACs in both directions), like TLS does. (Another way, used often for instant messaging, is OTR, the Off-the-Record messaging protocol.)
Without a way to identify the other end point, you end up with a way of allowing man-in-the-middle attacks. SSL/TLS without certificates, or with certificates where the man-in-the-middle knows the corresponding private key, is insecure, as is every other similar encryption scheme.
Another issue is that you said visitors of my website. This looks like you would implement client-side cryptography in JavaScript, delivered from your website. Don't do this ... if the visitors do not trust you not to read their data, they also should not trust you to feed them non-malicious JavaScript, which might implement something else than you are claiming it does, again allowing a MITM, or even directly sending a copy of the data to you.
More details about this are discussed in Javascript Cryptography Considered Harmful (from a slightly different perspective).
I'm designing a web service that clients connect to in order to retrieve some private data. Each client has a unique ID and a secret key (generated by the server) that are sent as parameters to the web service in order to authenticate itself. In addition, all communications are done over HTTPS.
I'm also planning to use HMAC-SHA256, in order to avoid sending the secret key over the wire.
However, I'm wondering whether this is strictly necessary. Since HTTPS gives me a secure channel between client and server, why would I really mind sending the secret key over that channel?
The only reason I managed to come up with is that an unknowledgeable developer might add a service in the future and not reject non-HTTPS connections, so hashing the secret key is a sort of insurance against the realities of corporate software development, an extra line of defense if you will.
Am I missing something more significant? Is this a real vulnerability that some attack vector could take advantage of?
An attacker installs a fake trusted certificate into a browser and hijacks the session.
A link to your site is sent, but the redirection to SSL is intercepted and a non-SSL session commences.
There are others, but the story is this: SSL is complicated and often attacked in inventive ways. If your connection is secure, then the hashing has little value compared to the complexity in code for humans and the cost in cpu time. However, if the SSL session is compromised, then you've still saved your key. Much as we hash passwords in databases despite the fact that nobody undesirable should have access, hashing your key despite SSL would be wise.
The channel may be secure, but that doesn't tell you anything about endpoints: depending on the browser in question (and its plugins/extensions/...), your key could very well end up in a disk-based cache somewhere on the user's computer, and it could sit there until the end of forever.
That is not a very interesting vulnerability ... until you realize that various malware already goes trawling through the disks, looking for anything valuable - and with the current rates, some of your users will be infected (unless your website only has twenty users ;)).
So: don't throw away a pretty powerful crypto mechanism to save a few CPU cycles; that's a potentially dangerous microoptimization IMNSHO.
Despite all the advices to use SSL/https/etc. I decided to implement my own security layer on top of http for my application... The concept works as follows:
User registers -> a new RSA Keypair is generated
the Private Key gets encrypted with AES using the users login Password
(which the server doesnt know - it has only the sha256 for authentication...)
Server stores the hash of the users password
and the Encrypted Private Key and Public Key
User logs in -> authenticates with nickname+password hash
(normal nick/password -> IP-bound sessionid authentication)
Server replies: sessionid, the Encrypted RSA Private Key
and an Encrypted randomly generated Session Communication Password
Client decrypts the RSA Private Key with the users Password
Client decrypts the Session Communication Password with the RSA Private Key
---> From this point on the whole traffic gets AES-encrypted
using that Session Password
I found no hole in that chain - neither the private key nor the login password get ever sent to the server as plaintext (I make no use of cookies, to exclude the possibility of the HTTP Cookie header to contain sensitive information)... but I am biased, so I ask - does my security implementation provide enough... security?
Why does everyone have to come up with their secure transport layer? What makes you think you've got something better than SSL or TLS? I simply do not understand the motivation to re-invent the wheel, which is a particularly dangerous thing to do when it comes to cryptography. HTTPS is a complex beast and it actually does a lot of work.
Remember, HTTPS also involves authentication (eg: being able to know you are actually talking to who you think you are talking to), which is why there exists a PKI and browsers are shipped with Root CA's. This is simply extremely difficult (if not impossible) to re-invent and prone to security holes. To answer you question, how are you defending against MITM attacks?
TLDR: Don't do it. SSL/TLS work just fine.
/endrant.
I'm not a crypto or security expert by any means, but I do see one serious flaw:
There is no way the client can know that it is running the right crypto code. With SSL/TLS there is an agreed upon standard that both your browser vendor and the server software vendor have implemented. You do not need to tell the browser how SSL works, it comes built in, and you can trust that it works correctly and safely. But, in your case, the browser only learns about the correct protocol by receiving plain-text JavaScript from your server.
This means that you can never trust that the client is actually running the correct crypto code. Any man-in-the-middle could deliver JavaScript that behaves identically to the script you normally serve, except that it sends all the decrypted messages to the attacker's servers. And there's no way for the client to protect against this.
That's the biggest flaw, and I suspect it's a fatal flaw for your solution. I don't see a way around this. As long as your system relies on delivering your crypto code to the client, you'll always be susceptible to man-in-the-middle attacks. Unless, of course, you delivered that code over SSL :)
It looks like you've made more complexity than is needed, as far as "home-grown" is concerned. Specifically, I see no need to involve assymetric keys. If the server already knows the user's hashed password, then just have the client generate a session id rolled into a message digest (symmetrically) encrypted via the client's hashed password.
The best an attacker might do is sniff that initial traffic, and attempt a reply attack...but the attacker would not understand the server's response.
Keep in mind, if you don't use TLS/SSL, then you won't get hardware-accelerated encryption (it will be slower, probably noticeably so).
You should also consider using HMAC, with the twist of simply using the user's password as the crypto key.
SSL/TLS provide transport layer security and what you've done does nothing but do that all over again for only the authorization process. You'd be better served to focus on authorization techniques like client certificates than to add an additional layer of line-level encryption. There's a number of things you could also introduce that you haven't mentioned such as encrypted columns in SQL Server 2008, IPSec, layer 4 & 7 hardware solutions and even setting up trusts between the server and client firewalls. My biggest concern is how you've created such a deep dependency on the username and password, both which can change over time in any system.
I would highly recommend that you reconsider using this approach and look to rely on more standard techniques for ensuring that credentials are never stored unencrypted on the server or passed in the clear from the client.
While I would also advocate the use of SSL/TLS for this sort of thing, there is nothing wrong with going re-inventing the wheel; it leads to innovation, such as the stack exchange series of websites.
I think your security model is quite sufficient and rather intelligent, although what are you using on the client-side? I'm assuming javascript since you tagged this post with 'web-development'? Or are you using this to communicate with a plug-in of sorts? How much overhead does your implementation produce?
Some areas of concern:
-How are you handling initial communication, such as: user login, registration?
-What about man-in-the-middle attacks (assuring the client that it is talking to the authorized server)?
The major problem you have is that your client crypto code is delivered as Javascript over unauthenticated HTTP.
This gives the Man-In-The-Middle plenty of options. He can modify the code so that it still authenticates with your server, but also sends the password / private key / plaintext of the conversation to him.
Javascript encryption can be enough when your adversary is an eavesdropper that can see your traffic but not modify it.
Please note that I am not referring to your specific idea (which I did not take the time to fully understand) but to the general concept of Javascript encryption.