Rigorous input testing, passwords, encryption - security is a feature no programmer can afford to overlook.
Safeguard your code: 17 security tips for developers
The scary stories from the Web are getting worse. First there were a few stolen credit card numbers. Now, millions of financial records are exposed by security breaches, and we grow numb to the threat.
Writing secure code begins long before the first loop is formed -- and is no easy task. To even approximate bulletproof code, architects, engineers, auditors, and managers must try to imagine everything that could go wrong with every aspect of the code. Although it's impossible to anticipate every nasty curve the attackers will throw, you have to do all you can to reduce your attack surface, plug holes, and guard against the fallout of a potential breach.
Here are 17 tips for producing more secure code.
Secure programming tip No. 1: Test inputs rigorously
Attackers need a path into your machines, and the easiest routes are through the doors your code opens. If your software takes input from the Internet, someone will try to sneak something past you.
The solution is to test the size and structure of the incoming data and never, ever trust the person on the other end of the Internet.
In general, programmers want to offer more flexibility and less enforcement. Checking every last bit of data is time consuming for the software and exhausting for the programmer. Data transport languages like XML and JSON don't do much to ensure that the data avoids these problems. But checking is what the programmers need to do to secure their code.
Secure programming tip No. 2: Store what you need, and not one bit more
Before you ask for your customer's snail mail address, ask yourself whether you will ever send them a letter through the post office. If email is sufficient, you might want to rethink storing home or business addresses. That information costs time to process, takes up disk space, and makes an attractive target for information thieves.
Programmers often think like obsessive hoarders, storing away copies of anything that stands the least chance of someday being useful. This instinct may help debug software, but it leaves a trail of data for anyone to find.
Is every column and table in the database absolutely necessary? When in doubt, make the forms shorter and the database tables smaller. Avoid the temptation to be a data pack rat.
Secure programming tip No. 3: Avoid trusting passwords more than necessary
Everyone knows the problem with passwords, but no one knows a better solution. Some companies are already using N-factor authentication by tossing several different hurdles in the way. It's always possible to add even more security with special hardware that locks up cryptographic keys. They are expensive, though, and even easier to lose than a cellphone. Other sites keep track of the IP addresses you use to log in. If you approach the system from unknown address, they send a polite email just in case.
None of these choices are perfect, but they are better than just relying on a password. The important step is recognizing the limitations of a string of characters regardless of the length and mixture.
Secure programming tip No. 4: Negotiate requirements
Building secure code is not just something that happens in the code editor. When managers draft requirements and discuss them with developers, everyone should seriously consider how each requirement could open the door to problems down the road.
A feature may be cute, but will it force you to keep additional sensitive information and increase the level of security required everywhere? Is a slick feature worth the extra headaches? The right time to start securing your code against future breaches is when the requirements document is still flexible and the customers aren't salivating over the features you've promised them.
Secure programming tip No. 5: Add delays to your code
Many attacks rely on brute force. It may take trillions of iterations, but the computer doesn't care. Some bots screenscrape databases by sending millions of queries. Others try trillions of passwords until the right one is found.
The trick is to add progressively more delay to confound these bots. You want your software to be fast enough to support the right humans but too slow for attacking bots to accomplish much.
Some login programs double the delay with each incorrect password. Some databases limit the number of queries from each IP address. Some systems deliberately send an email request to slow you down. Humans won't notice the extra second or two, but a bot will be bored to the point of being ineffective.
Secure programming tip No. 6: Use encryption more often than you think you should
Encryption is often underused because it adds yet another step to the machinery and makes debugging that much harder. It can be difficult enough to find errors in a system; it's even tougher when the data is an inscrutable pile of numbers.
But what's inscrutable to you is also inscrutable to attackers. Locking up personal data before storing it in the database saves you from worrying about the database, the underlying OS, and to some extent the hypervisor that might be running underneath.
The right amount of encryption doesn't need to reduce functionality. I examined a number of different examples in my book "Translucent Databases" that can provide useful services while protecting personal information. Plus, extra protection is itself a feature.
Secure programming tip No. 7: Build walls
Security often competes with the demand for ease-of-use. People hate logging in to different parts of the system, but it can be dangerous to link everything to one portal. There is no easy way to decide how easy it should be for a user to navigate the system and accomplish what they want with a click. The easier you make it for legitimate users, the easier you make it for attackers.
It can make sense to segregate the most sensitive operations into a separate system and require people to log in again when they use it. A bank might give a portal the ability to check status and deposit money but require substantially more authentication before money is withdrawn.
Secure programming tip No. 8: Tested libraries -- use them
Encryption is hard to do well, and even the best theory and carefully built code can have loopholes and backdoors. It's usually a mistake to reinvent a well-tested library, but it's even more problematic with encryption. Well-tested libraries are more important in this field than others. Choose better code here and don't invent your own algorithms.
Secure programming tip No. 9: Use internal APIs
Breaking your code into modules and enforcing communication through well-designed APIs is an old lesson everyone learns early in their career. It's even more valuable for security because APIs can make it simpler to audit interactions, find holes, and fix problems. Modules can be scrutinized individually, and the results can be combined.
It often makes sense to create internal submodules as well; the same idea applies inside of modules, too. Parts are easier to analyze than the whole.
Secure programming tip No. 10: Bring in outside auditors to critique your code
Each of us can use an editor. If an enterprise is investing in a well-built installed base, it should also be investing in code audits. These can identify flaws and generate suggestions for improving the code.
In general, more eyeballs looking over the code can spot problems that may occur. Outsiders can also unjam internal political logjams and break ties. They often don't know any more than insiders, but they have the advantage of being unaffiliated with internal factions.
Secure programming tip No. 11: Code analyzers are your friend
Though far from perfect and not as smart as a human, code analyzers can be worthwhile. After all, they're diligent, and they don't get tired, thirsty, hungry, or bored.
Code analyzers like the FindBugs tool from the University of Maryland can look for common mistakes we make when we're not thinking. Many of these mistakes have little to do with security, but some can be fatal.
Secure programming tip No. 12: Limit privilege
Developers love to think ahead, and giving someone all the access they might need is a simple way to plan for the future. While leaving doors open can help handle future chores and avoid creating roadblocks for users and staff, the open doors, as mentioned in tip No. 1, are often the first pathway that's abused. A good principle is to give code and people the smallest amount of privilege needed to get the job done.
If this turns into a management headache generating too many requests for extra privileges, it may make sense to rethink the architecture for the data. Are you keeping too much information? If people need more access than you're comfortable giving, you may be storing too much information.
Secure programming tip No. 13: Model your threat
Do you hold credit card numbers? Then a common thief may be after your information. Do you track people's location with their cellphones? The dangers grow creepier.
Spending time thinking about who wants your data can be a useful precursor. If you can imagine a threat, you can keep the attacker in mind while you design and implement the system. They present an antiuse case to avoid.
It's important to recognize that no list or model will ever be perfect. Just because the threat isn't imagined doesn't mean you don't have to worry about it. It's just a start.
Secure programming tip No. 14: Trust goes both ways
It's easy to be suspicious of those who log into your website, but remember that they should be suspicious of you, too. Are you really the bank that holds their money, or are you a phishing website trying to steal everything they own?
Some sites are investing in proving themselves to the customers. They ask the customer to upload some photo or set of words that the website can use to prove that they're who they say they are. This can make everyone more secure.
Secure programming tip No. 15: Keep apprised of the latest threats
Following the industry press is absolutely essential, and InfoWorld is just one of the publications that covers tragic mistakes. Good articles can show you what others did wrong and give you a chance to think like an unauthorized prowler.
Understanding what happened in the past is a good way to begin planning for the future when a similar attacker may come after you -- a similar attacker who is also reading the same articles and thinking about them in a more malicious way. Once the ideas are out there, you have to take notice or the attackers will get a jump on you.
Secure programming tip No. 16: Deep research can pay off
The daily press is the first draft of how not to step in deep manure. Better lessons come from reading the books and journal articles written after the researchers have had time to think about what went wrong. These often include good rules and methods for avoiding the problem in the future.
Investing some time and money in books is often an incredibly cheap way to get knowledge from some of the most highly paid consultants. A book that costs $200 or $300 may seem outrageously expensive, but not when the consultant also charges $500 an hour and insists on a 20-hour minimum.
Secure programming tip No. 17: Educate yourself
You can enroll in a local university or try one of the new free courses online. These are different ways of learning the information that often hasn't been distilled and put in book form. The professors are usually following the latest publications in academic conferences, and they likely include copious footnotes and pointers. Even if you know much of the information already, auditing a course helps you keep current with the latest discoveries and publications.