IBM®
Skip to main content
    Country/region [select]      Terms of use
 
 
      
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks > Security >
developerWorks
Software security principles: Part 5
e-mail it!
Contents:
Principle 8: It's hard to hide secrets
Principle 9: Don't extend trust easily
Principle 10: Trust the community
Conclusion
Resources
About the authors
Rate this article
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)
On keeping secrets, trusting others, and following the crowd

Gary McGraw (gem@cigital.com), Vice president of corporate technology, Cigital
John Viega (viega@cigital.com), Senior research associate and consultant, Cigital

01 Dec 2000

In this series, Gary and John present a set of 10 principles that can help you remove the majority of security problems from your code. Here, they finish up with the last three principles. First, they examine why you shouldn't expect to successfully hide secrets in your systems, at least not without great effort. Second, they emphasize that it's important to be wary of extending trust to anyone, including yourself. Third, they advise that when we do need to trust, it's sometimes a good idea to follow the herd.

Principle 8: It's hard to hide secrets
Security is often about keeping secrets. Users don't want their personal data leaked, so you need to keep cryptographic keys secret to avoid eavesdropping or tampering. You also want your top-secret algorithms to be protected from your competitors. These kinds of requirements are important, but far more difficult to satisfy than the average user suspects.

Many people assume that secrets in a binary are likely to stay secret, because it is too difficult to extract them. Yes, binaries are complex, but it's incredibly difficult to keep the "secrets" secret. One problem is that some people are actually quite good at reverse engineering binaries -- that is, pulling them apart, and figuring out what they do. This is why software copy protection schemes tend to be inadequate. Skilled hackers can generally circumvent any protection that a company tries to hard code into its software, and release "cracked" copies. For years, there was an escalation in the number of techniques being used; vendors would try harder to keep people from finding the secrets to "unlocking" software, and the software crackers would try harder to break the software. For the most part, the crackers won. Cracks for interesting software have been known to show up on the same day the software is officially released -- sometimes sooner.

If your software all runs server-side on your own network, you might decide that your secrets are safe. Actually, it's much harder than that to hide secrets. You shouldn't trust your own network if you can avoid it. What if some unanticipated flaw permits an intruder to steal your software? This is what happened to Id software right before they released the first version of Quake.

Even if your network is as secure as possible, your problems may lie within. Several studies have shown that the most common threat to companies is the "insider " attack, where a disgruntled employee abuses access. Sometimes the employee isn't even disgruntled; maybe he just takes his job home, where a friend goes prodding around where he shouldn't. Also, many companies would not be able to protect their preciously-guarded software from a malicious janitor. If people are intent on getting your software through illegal means, they will probably succeed. When we point out the possibility of an inside attack to people, they often respond, "That won't happen to us; we trust our employees." If you're thinking the same thing, you should be wary. Ninety percent of the people we talk to say the same thing, yet most attacks are perpetrated by insiders. There's a huge gap here; most of the people who believe they can trust their employees must be wrong. Remember, employees may like your environment, but when it comes down to it, most of them have a business relationship with your company, not a personal one. The moral here is that it pays to be paranoid.

Sometimes people don't even need to reverse engineer software to figure out its secrets. These can often be discovered just from observing the software at work. For example, we (John Viega and Tim Hollebeek) once broke a simple cryptographic algorithm in the Netscape e-mail client simply by observing its behavior with a series of chosen inputs. (It was so easy to do that we were quoted as saying, "We didn't do this with just a pencil and paper. Lots of our notes are in pen. We didn't need to erase much.") More recently, E*Trade was the subject of a similar fiasco -- anyone could see your username and password as you logged in over the Web.

The practice of trusting a binary (or any other form of obfuscation, for that matter) to keep secrets for you is affectionately termed "security by obscurity" (see Resources). Whenever possible, you should avoid using this as your sole line of defense. That doesn't mean that there is no place for security by obscurity. Denying access to the source code definitely raises the bar for an attacker -- somewhat. Obfuscating the code to produce an obfuscated binary helps even more. These techniques require that potential attackers posses more skill than they would otherwise need to actually break your system, and that is usually a good thing. On the flip side, most systems protected this way fail to go through an adequate security audit; there is something to be said for openness, which allows you to obtain free security advice from your users.

Principle 9: Don't extend trust easily
People might more often realize their secrets are at risk if they understood that they can't trust clients that are in the hands of end users, because end users can't be trusted to use clients as they were intended. We've also urged you to be reluctant to trust your own servers, in case they get hacked (see Principle 3: Compartmentalization, referenced in Resources). This hesitancy should permeate all aspects of your security process.

For example, while off-the-shelf software can certainly help you keep your designs and implementations simple, how do you know you can trust an off-the-shelf component to be secure? Do you really think the developers were security experts? Even if they were, do you expect them to be infallible? There have been tons of products from security vendors with gaping security holes. Many people in the security business don't actually know very much about writing secure code.

Another place where trust is generally extended far too easily is in the area of customer support. Social engineering attacks are incredibly easy to launch against unsuspecting customer support agents, who have a proclivity to trust, because it makes their jobs easier.

You should also be careful about "following the herd." Just because a particular security feature is standard doesn't mean you should provide the same poor level of protection. For example, we've often heard people opt not to encrypt sensitive data simply because their competitors weren't encrypting data. That won't be much of an excuse when customers get attacked, and then look to blame someone for being lax with security.

You should be skeptical of security vendors, too. They very often spread shady or downright false information in order to sell their products. Generally, such "snake oil" peddlers work by spreading FUD -- Fear, Uncertainty, and Doubt. Many common warning signs can help you detect quacks. One of our favorites is the advertising of "million-bit keys" for a secret-key encryption algorithm. Mathematics tells us that 256 bits is likely to be sufficient to protect messages through the lifetime of the universe -- assuming the algorithm is of high quality. People advertising more know too little about cryptography to sell worthwhile security products. Before you finish your shopping, make sure to do your research. One good place to start is the "Snake Oil" FAQ (see Resources).

You should also be reluctant to trust yourself and your organization. It's easy to be short-sighted when it comes to your own ideas and your own code. While you might like to be perfect, you should admit that you're not, and get a high-quality, objective outside perspective on what you're doing periodically.

One final point to remember is that trust is transitive. Once you give it to an entity, you implicitly extend it to anyone that entity may trust. For this reason, trusted programs should never invoke untrusted programs. You should also be careful when determining which programs to trust; programs may have hidden functionality that you do not expect. For example, in the early '90s, one of us had a UNIX account with extremely limited, menu-driven functionality. You started out in the menu when you logged in, and could only perform simple operations, such as read and compose mail and news. The menu program trusted the mail program. The mail program would call out to an external editor (in this case, the "vi" editor) when the user was composing mail. When composing mail, the user could do some vi magic to run an arbitrary command. As it turned out, it was easy to leverage this implicit, indirect trust of the vi editor to get rid of the menu system altogether, in favor of a regular old unrestricted command-line shell.

Principle 10: Trust the community
While it's not a good idea to blindly follow the herd, there is something to be said for strength in numbers. Repeated use without failure promotes trust. Public scrutiny does as well. (That is the only time this principle applies; otherwise, Principle 9 is the correct one to apply, and you should ignore this one.)

For example, in cryptography it's considered a bad idea to trust any algorithm that isn't public knowledge and hasn't been widely scrutinized. There's no real solid mathematical proof of the security of most cryptographic algorithms; they're trusted only when a bunch of smart people spend a lot of time trying to break them, and all fail to make substantial progress.

Many people find it alluring to write their own cryptographic algorithms, hoping that if these algorithms are weak, security by obscurity will serve as a safety net. Repeatedly, such hopes are dashed (for example, with the Netscape and E*Trade breaks mentioned above). The argument generally goes that a secret algorithm is better than a publicly-known one. We've already discussed how you should expect your algorithm not to stay secret for very long. For example, the RC4 encryption algorithm was supposed to be a trade secret of RSA Data Security. However, it was reverse engineered and posted on the Internet anonymously soon after its introduction.

In fact, cryptographers design their algorithms so that knowledge of the algorithm is unimportant to security. Good cryptographic algorithms work because you keep a small secret called a "key," not because the algorithm is secret. That is, the only thing you need to keep private is the key. If you can do that, and the algorithm is actually good (and the key is long enough), then even an attacker who's intimately familiar with the algorithm will be unable to attack you.

Similarly, it's far better to trust security libraries that have been widely used, and widely scrutinized. Sure, they might contain bugs that haven't been found -- but at least you get to leverage the experience of others.

This principle only applies if you have reason to believe that the community is doing its part to promote the security of components you want to use. One common misconception is the belief that "open source" software is highly likely to be secure, because source availability will lead to people performing security audits. There's strong evidence to suggest that source availability doesn't provide the strong incentive for people to review source code, even though many people would like to believe that incentive exists. For example, many security bugs in widely-used, free software programs went unnoticed for years. In the case of the most popular FTP server around (WU-FTPD), several security bugs went unnoticed for more than a decade!

Conclusion
In the past five installments, we've talked about a set of general principles that we think can help you avoid most security problems. The principles are:

  1. Identify and reinforce the weakest link.
  2. Provide defense in depth, which means you should manage software risk by providing redundant security solutions. Usually, one level of redundancy is worthwhile; whether you need more depends on your particular project.
  3. Secure failure: Make sure that if the system could possibly fail, it will fail in a secure manner.
  4. Least privilege: Do not give out more privileges than necessary, and do not extend privileges longer than necessary.
  5. Compartmentalization: Try to keep failures in one part of a system from having an impact on the rest of the system.
  6. Keep it simple.
  7. Privacy: Don't give out any unnecessary information.
  8. It's hard to hide secrets.
  9. Don't extend trust easily.
  10. Trust the community.

Remember that it's important to apply good software risk management techniques when using these principles. You should only apply principles when such a strategy tells you that it is cost effective to do so. Also, these principles can sometimes work to contradictory ends, so such a strategy is even more crucial. Finally, we certainly don't expect that this set of principles will cover every situation you might encounter, but it should do a good job in general.

Resources

  • Part 1 of this series emphasizes the importance of reinforcing the weakest -- and most susceptible -- parts of your system (Principle 1).

  • Part 2 focuses on defense in depth (Principle 2) -- which advocates the use of multiple defense strategies -- and secure failure (Principle 3) -- the notion that system failure is not necessarily the same as system vulnerability.

  • Part 3 emphasizes controlling access through least privilege and compartmentalization, Principles 4 and 5, respectively.

  • Part 4 examines the importance of simplicity (Principle 6) and privacy (Principle 7).

  • In a previous developerWorks article, "Make your software behave: Assuring your software is secure," Gary and John lay out their five-step process for designing for security.

  • Cigital is a leading authority on software risk management -- check out their site.

  • In "Make your software behave: Security by obscurity," Gary and John discuss the pitfalls of keeping secrets.

  • The "Snake Oil" FAQ can help you sort through the myriad security vendors to find the most reliable ones.

  • The developerWorks columns by Gary and John have been updated and expanded in the book Building Secure Software, which also includes plenty of new material. Pick up a copy today -- your users will thank you.

About the authors
Gary McGraw is the vice president of corporate technology at Cigital (formerly Reliable Software Technologies) in Dulles, VA. Working with Consulting Services and Research, he helps set technology research and development direction. McGraw began his career at Cigital as a research scientist, and he continues to pursue research in software engineering and computer security. He holds a dual Ph.D. in Cognitive Science and Computer Science from Indiana University and a B.A. in Philosophy from the University of Virginia. He has written more than 40 peer-reviewed articles for technical publications, consults with major e-commerce vendors including Visa and the Federal Reserve, and has served as principal investigator on grants from Air Force Research Labs, DARPA, National Science Foundation, and NIST's Advanced Technology Program. He can be reached at gem@cigital.com.


John Viega is a senior research associate, Software Security Group co-founder, and senior consultant at Cigital. He is the principal investigator on a DARPA-sponsored grant for developing security extensions for standard programming languages. John has authored over 30 technical publications in the areas of software security and testing. He is responsible for finding several well-publicized security vulnerabilities in major network and e-commerce products, including a recent break in Netscape's security. He is also a prominent member of the open source software community, having written Mailman, the GNU Mailing List Manager, and, more recently, ITS4, a tool for finding security vulnerabilities in C and C++ code. Viega holds an M.S. in Computer Science from the University of Virginia. You can contact him at viega@cigital.com.



e-mail it!
Rate this article

This content was helpful to me:

Strongly disagree (1)Disagree (2)Neutral (3)Agree (4)Strongly agree (5)

Comments?



developerWorks > Security >
developerWorks
  About IBM  |  Privacy  |  Terms of use  |  Contact