Monday, March 24, 2008

Measuring the Wrong Things?

I'm not sure why I'm always finding interesting articles in NPR about medicine that seem to resonate so much in relation to software security. Nonetheless that seems to be how things go, so here comes another one.

NPR ran a story the other day titled "Doctors' 'Treat the Numbers' Approach Challenged". The main idea in the story is that doctors have been treating patients and using the results of certain tests as the metrics by which they judge health. They treat a patient with drugs, therapies, etc. to get to the diagnostic numbers they want, but now we're finding out that perhaps the numbers are not necessarily representing what we'd like them to.

The example from the article was:

Doctors call it "treating the numbers" — trying to get a patient's test results to a certain target, which they assume will treat — or prevent — disease. But earlier this year, a study on a widely used cholesterol drug challenged that assumption.

Vytorin, a combination of two cholesterol-lowering agents, certainly lowers cholesterol. But patients taking it didn't have any less plaque in a major artery than those taking a less-potent drug.

I'm assuming that less plaque generally does translate to fewer adverse events, but the article doesn't cover this. Helpfully, in medicine we generally have a pretty clear definition of an adverse event, and we're not dealing with intelligent active threats. Active threats (virus, bacteria, fungus, parasite), but not intelligent... We don't try to design cholesterol treatments to fend off a malicious food company that has designed a new more dangerous form of cholesterol that our drug can't fight :)

Knowing what to measure in security is hard though. We've covered a little of this before here.

If you're looking for more formal treatments of security metrics - check out the Quality of Protection (QoP) workshop held as part of the ACM CCS Conference.

"The goal of the QoP Workshop is to help security research progress towards a notion of Quality of Protection in Security comparable to the notion of Quality of Service in Networking, Software Reliability, or measures in Empirical Software Engineering."

Over the next few posts I'll take a few of the papers from the workshop and discuss a bit of their results. If you're interested in the TOC for the workshop, you can find it here.

Tuesday, March 18, 2008

Banning function calls, assurance, and retrofitting

I've been working on some C/C++ secure coding standards lately, and trying to mesh those up with the results from the static analyzer I'm using. As it turns out there is a fine line to be drawn between what you consider best practices, what a static analyzer can find, how much context the static analyzer has, and how much manual review you really want to put up with.

Let me give a specific example.

Coverity's Prevent analyzer has a number of built-in "unsafe" functions defined. The list includes the standard cast such as scanf, strcpy, strcat, etc. On top of that though they add some things that didn't make Microsoft's list; for example, rand().

I don't technically have a problem with including rand() in the list of things to be extremely careful about, but whereas it is nearly impossible to guarantee that someone has used strcpy() right, rand() actually has some pretty legitimate uses.

Consider the case where we want to do a randomized delay in processing something, or where we wish to randomly assign work to different people when it comes in, or randomly pull an item off a work queue for a customer service agent. None of these cases requires a cryptographically sound random number generator. For the most part, using rand() is a perfectly reasonable choice in this sort of situation.

When you decide that you want to ban certain function calls, or call them out in findings in a static analyzer, you're treading a fine line with your developers and the people you're going to ask to go and clean up the old code you have around. You can choose to go several routes.

  • File defects against the old code for any use of a banned function, without investigating the specific use
  • File defects against old code only after verifying that in the context you have a potential vulnerability
  • Get a dedicated team together to just go and clean up old code
Each of these approaches has its plusses and minuses.

If you choose to file defects against your developers for code that is years old and wasn't necessarily written by them without verifying the vulnerabilities, you run the risk of them not taking the secure coding rules seriously. Many of the items they find are going to be false positives from a currently-exploitable perspective, and they are going to be cranky with you.

If you choose to go through the validate each and every defect and the types of defect are pervasive, you're going to spend almost as much verifying the defect as fixing it. Especially if you're going through and simply replacing strcpy() with strlcpy() for example. For both this and the case above though, developers are going to be going through the code, and with the proper training/awareness, they might actually learn more about some of the old code, or at least start to have a better sense of some real security issues in the code.

If you choose to get a dedicated team together to fix the old code, you're likely to save money in the short run. A dedicated team is going to get used to fixing the coding defects of this type, and you're going to make a lot shorter job of it. The downside being that the regular developers aren't getting some of the code review experience you'd really like.

To top things off, if you go route #2, wherein you only fix things that are currently exploitable, you run the risk of the code being used in a different way elsewhere and causing problems down the road.

Back to my rand() example. In every case where I've found rand() used it hasn't been in a security critical context. Do I want to leave these instances of rand() in my code as examples that others might follow, next time in a security sensitive context? Or, do I want to take a relatively dogmatic approach to this and all other banned/"unsafe" functions and eliminate them entirely from my codebase?

I'm leaning towards some sort of middle ground. If I can find the time for a dedicated team to go through the code to clean up old issues, then I'm likely to remove all instances of things that could be unsafe, just so we don't leave things around that could be copied into an truly unsafe context.

Its a tricky balancing act to determine how dogmatic you want to be about fixing up the use of certain "unsafe" functions. Getting it wrong either way can have long term consequences for your secure development program. As always, the right answer depends on a lot of factors.

Monday, March 17, 2008

Good Economist Article on Software Security

Last week the Economist ran their Technology Quarterly series and had a great piece on software security, quality. The title was "Software that makes software better."

The Technology Quarterly is a great read that covers quite a number of new/evolving areas of technology such as improvements in battery design/lifetime, new pico-projectors, and this time a great article about software quality and security.

The article is a quick run-through of integrating quality and security concerns into the development process through the judicious use of tools. The two major items of note from the paper were:

1. Integrating the tools with how developers usually work is key
2. We still don't really have any idea what we're doing :)

From a metrics perspective, the most important line was this one from NIST:

America's National Institute of Standards and Technology (NIST) is doing its best to create the software equivalent of the “generally accepted accounting principles” used in the financial world. Its Software Assurance Metrics and Tool Evaluation (SAMATE) project is intended to offer companies a way to quantify how much better their code will be if they adopt particular tools and programming languages. Paul Black of NIST says its first report, on static-analysis tools, should be available in April. The purpose of the research is “to get away from the feeling that ‘all software has bugs’ and say ‘it will cost this much time and this much money to make software of this kind of quality’,”

I added the emphasis above. That line from Paul is a pretty ambitious statement - though who knows whether the reporter really got the quote right. Overall the SAMATE project is an important aspect of increasing assurance, but I'll be surprised if we manage to boil things down to do this, this, and this, it will cost X, and you'll be Y-secure.