Home‎ > ‎

Security Tips

  • Never invent your own cipher
    Only use algorithms that have been vetted by the security community for at least a decade. You want whatever has come out on the other side of the gauntlet alive, kicking and improved. You cannot duplicate this enormous public grilling process on your own. Rolling-your-own crypto is famously notorious for dooming both products, businesses, and careers

  • Never write your own implementation of a well-known cipher
    Even if the algorithm is a standard like AES, the algorithm is just a mathematical concept, meaning any given implementation could have weaknesses that come from things you never knew about your language, platform, or even the hardware (such as side-channel attacks). Somebody else has figured these things out already, such as the vendor or a dedicated third party

  • A cipher alone is never enough
    A cryptosystem is made of more than one cryptographic part, and there's almost never a real-world situation where a cipher alone is enough. For a start, you will need to use a mode such as Cipher Block Chaining (CBC) or Counter (CTR) to remove any patterns that might leak through to the ciphertext. Second, you should also use Message Authentication Codes (MACs) to prevent tampering. Third, you will often need a key exchange protocol, such as Diffie-Helman, if you need to establish a secure connection between two parties. The construction of cryptosystems is covered well in the book Practical Cryptography by Ferguson and Schneier

  • Never store simple hashes of credit cards
    You may think you're being secure by hashing a credit card number and storing that, but a database of hashed card numbers can be brute-force cracked on a desktop PC in a few days--even without the use of rainbow tables--by taking advantage of the fact that card numbers are short and contain well-known patterns. For example, the attacker knows the majority of the cards will be issued by banks like Citi and Chase, who's first 6-digit bank codes are well known. Plus, you'll probably find that you need to store the last-4 digits in plaintext in order to identify the card in emails and phone calls with the customer. There is no safe way to store credit card numbers in a searchable form, and my advice is to either use a gateway service that stores the numbers for you, or to use hash strengthening techniques (salt and re-hash the number 200,000 times or more), then buy some liability insurance and hire a good law firm and PR agency

  • Don't make decisions based on headlines
    "MD5 has been cracked" is an accurate headline, and many places where MD5 is used must now be switched to a better hash, but analyze your usage before you knee-jerk your team into replacing it with, say, SHA1. Many applications remain secure with MD5 simply because they were designed so that hash collisions wouldn't be a useful form of attack against them. Reacting to every news headline may just distract you from performing a proper security analysis that'd uncover holes no journalist will ever warn you about 

  • Prefer certificates over Yet Another Fucking Password
    Use Windows Authentication, RADIUS, Kerberos or other Single Sign-On methods instead of forcing username/password logins everywhere. Also consider using Certificate Authority (CA) software to create certificates for each user on the network, using those certificates to sign any data submitted to the database. And don't throw away the digital signatures after you've validated them and updated the database: use them to audit the system to detect tampering

  • Group privileges by roles, not job positions
    Don't group powers and privileges into positions like "Administrator", "Supervisor" or "Executive". Instead, come up with task-specific roles such as "Data collector", "Editor", "Negotiator", "Quality Checker", and so-on. Assign roles to each user separately and give them more roles as they gain training or promotions. Avoid creating "God" roles

  • Use SecureString for passwords, credit cards, Social Security numbers and other sensitive values
    In .Net and some other platforms, a SecureString is a string value that gets encrypted in memory. It's also marked with flags that tell the Garbage Collector not to make more than one copy of it. The PasswordBox control in WPF stores its values in SecureStrings and there are an increasing number of other classes that take them without forcing you to decrypt and copy it to a plain string
    • Caveat: Do not depend on SecureString for all of your security. All it does is make sure the plaintext never hits a swap file or a memory dump

Voodoo security

  • Forcing password changes every x months
    Users lose track of them early and write them down on post-it notes attached to their monitors. It's better that they have one strong password that they've memorized. Have them change their password every year at most

  • Restricting the characters that can be used in passwords
    If it can be typed on a keyboard then it should be possible to use it in a password. Even the characters you can only type by holding down the Alt-key and typing the ASCII value. By restricting valid characters, you're shortening the keyspace a hacker needs to search through in a brute-force attack

  • Blindly cranking up the bits
    256-bit AES is not necessarily better than 128-bit AES (in fact, it may be worse), and SHA-384 is not necessarily better than SHA-256. It's a good idea to go higher than 512 or 1024-bits for RSA keys, of course, but 8192-bit keys might not gain you anything for a while and could even lull you into a false sense of security
Further reading: Snake Oil Cryptography by Bruce Schneier.