Redemption Steps

Generally , we recommend using SSL/TLS for any network connections, if at all possible, or else some other abstraction, such as Kerberos. Be sure to use SSL in accordance to our guidance in Sin 10, though. Sometimes people dont expect that incorporating SSL is possible, particularly when using a third-party executable in their program that doesnt support it, but there are actually SSL proxies, such as Stunnel. Similarly, you might use IPSec or some other VPN technology to help reduce exposure to these kinds of problems.

Sometimes it really isnt feasible to support SSL/TLS. One reason may be that you need to communicate with clients or servers you dont control that dont speak the protocol. Thats a situation where youll just have to decide whether or not to accept the risk.

Another reason some people want to avoid SSL/TLS is because of the authentication overhead. SSL uses public key cryptography that can be expensive, and it can potentially leave you open to denial of service attacks. If this is a big concern, there are certainly network-level solutions, such as load balancing, that you can use.

Low-Level Recommendations

Okay, so youre not willing to take our advice and use an existing high-level abstraction, such as SSL/TLS or Kerberos. Lets revisit the basic security services on the wire: confidentiality, initial authentication, and ongoing authentication.

One of the most important things to protect with a confidentiality mechanism is generally authentication information. Good authentication protocols will provide their own confidentiality mechanisms, but the most popular protocols arent good ones. Thats why password-based authentication with SSL/TLS is generally done to authenticate a client only, and is done over the encrypted channel, hopefully once the client has authenticated the server (thus guaranteeing that the credentials will remain confidential while on the network).

There are subtleties to getting these security services right. Both initial authentication and ongoing authentication will generally want to protect against replay attacks, which requires some sort of proof of freshness. Initial authentication protocols usually use a three-phase challenge-response to solve this problem. You should absolutely avoid designing your own initial authentication protocol because these things commonly have incredibly subtle problems when theyre not designed by a skilled cryptographer. Heck, they often have such problems when they are designed by a cryptographer!

Ongoing authentication protocols generally have a message counter to thwart replay attacks. The counter is often part of the inputs to the ongoing message authentication algorithm (which can be the encryption algorithm itself, incidentally), but can be in the actual data field, as well. One key factor here is that the receiving end has to be sure to reject out-of-order messages. This can be infeasible for connectionless protocols. Therefore, it is common to use a sliding window of message counters, where dupes will be detected and nothing before or after the window will be accepted.

Also, both initial authentication mechanisms and ongoing authentication mechanisms can be a sizable denial of service risk if they make heavy use of public key cryptography. For instance, if you allow PGP-signing for individual IMs, an attacker could send lots of messages with bogus signatures very cheaply and tie up your CPU. Or, if theres some sort of throttling mechanism in place, it can keep out legitimate traffic.

Its much better to use secret key cryptography for authentication as soon as possible. In fact, SSL/TLS has an option called session caching that allows connections to authenticate using symmetric key cryptography once theyve authenticated a single time using a more intricate connection mechanism.

Another subtlety of using public key cryptography for message authentication is that it provides strong evidence on who sent what data, which could potentially be used in a court of law (this is called nonrepudiation). The sender cant claim he didnt send the message once he signs the message. Plus, its reasonable to expect that excuses such as I didnt do it; someone broke into my computer/gave me a virus, will sometimes be accepted as perfectly valid, diminishing the value of nonrepudiation. Generally, its probably better to avoid signatures for message authentication, not just because of the denial of service risk of the heavy cryptography, but also to leave room in your systems for plausible deniability, except when explicitly demanded. That is, your users may appreciate it if theres no mechanism that could get them in trouble for slips of the tongue, making jokes that are misinterpreted, and things that are taken out of context.

Confidentiality also has its subtleties, some of them cryptographic, and some of them practical. For instance, there are cases where its insecure to encrypt data and authenticate the same data in parallel, or even to encrypt the authenticated data. The only general strategy that is secure is to encrypt the data first, then authenticate it. If confidentiality isnt important, then authenticating unencrypted data is just fine.

Also, common confidentiality mechanisms are often misused because developers dont properly understand the requirements for using those mechanisms securely. In particular, its common to misuse both block ciphers being run in cipher block chaining (CBC) mode and the RC4 encryption algorithm.

With CBC mode, the input is not only a plaintext to encrypt, but also a random initialization vector. If the vector isnt random, then attacks may be possible. This is even true when subsequent messages use the last block of the previous message as an IV. This is one of the many reasons why the new block cipher modes of operation that provide both confidentiality and ongoing message authentication in one construct avoid CBC-like constructs. SSL/TLS fell prey to this kind of problem, as you will see.

RC4 has had some serious weaknesses, and is broken enough that you shouldnt be willing to send a lot of data through it (no more than 2 20 bytes to be safe). Things look bad enough for RC4 that we strongly recommend you dont use it at all if you want your system to be secure in the long term . But, even if you just use it to encrypt a little bit of data, you still need to initialize the algorithm using one of the following best practices:

  • Key the algorithm as normal, and then throw away the first 256 bytes of keystream (that is, encrypt 256 bytes of 0s and throw the results away without disclosing them). A problem here is that this may not actually be enough data to throw away.

  • Pass the key through a one-way hash function, such as SHA1, and then use the result to key RC4. This is the better practice. Recent attacks on SHA1 wont have any practical impact on this technique.

Another subtle aspect about confidentiality is that paranoid people generally want end-to-end security. For instance, privacy advocates generally wont use instant messaging services, even if they encrypt to the server, because the server is an unnecessary point of weakness that is vulnerable not only to attackers , but also to subpoenas, and so on. Most people prefer privacy, but are willing to sacrifice it. Since thats the case, its often good to provide as much data confidentiality as possible, especially since not providing confidentiality can lead to identity theft. We are starting to see that weak systems that give up user data may be held accountable. For example, if you do business in California, you now have to alert users when there is a known compromise of data they expected to be private. Eventually, such requirements could be augmented with financial penalties and other legal consequences.

Sometimes people still feel a need to do something simple based on symmetric key cryptography, since it is exceptionally fast and lightweight in comparison to SSL. This is not something we recommend at all because there are many ways to shoot yourself in the foot . The encryption itself isnt so difficult to get right if you use the right primitives, but the key management can be a nightmare. For example, how do you store keys securely and be agile about moving an account between machines? If the answer is a password, then there are some serious issues here, because as long as youre using purely symmetric key cryptography, there are going to be offline brute-force guessing attacks.

If youre going to go the all-symmetric route, even after all our warnings that youre better off learning how to use an off-the-shelf solution properly, then heres some guidance for you:

  • Use a trusted block cipher. We strongly recommend AES and a minimum key size of 128 bits, no matter what algorithm you choose.

  • Use the block cipher in a mode of operation that provides both authentication and integrity, such as GCM or CCM. If your crypto library does not support these, you can easily obtain such libraries (see the Other Resources section). Or, another option is to use two different constructs in combination: CTR mode and either CMAC or HMAC.

  • Apply ongoing authentication to the entire message, even in situations where you dont have to encrypt all of the data. Modes like GCM and CCM allow you to provide message authentication to data that you dont want to encrypt.

  • On the receive side, always check to make sure that the message is authentic before doing anything with it.

  • Also, on the receive side, check to make sure that the message is not a replay (and reject it if it is). If the message is authentic, this is done by comparing the message number with the last seen message number, which should always be increasing.

By the way, if you need to be able to prove to third parties that somebody sent a particular message, you can also use digital signatures, but do that only when necessary, and do it in addition to whatever other ongoing message authentication algorithm you use.

On Windows systems, RPC/DCOM calls can do proper per-packet integrity checking and privacy along with authentication merely by changing one parameter in how you set up the session. Again, the best way to handle this problem is to leave it to others. Additionally, the SSPI API can be used to set up network transfers relatively easily using HTTPS or Kerberos, which will authenticate both the client and the server and can provide for packet integrity and privacy.



19 Deadly Sins of Software Security. Programming Flaws and How to Fix Them
Writing Secure Code
ISBN: 71626751
EAN: 2147483647
Year: 2003
Pages: 239

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net