Security has become a hot global topic. Banks make a point to advertisethe security of their online services. Credit cards boast built-insecurity chips. The press regularly reports of computer vulnerabilitiesand attacks wrecking havoc among unsuspecting computer users.
Even more disturbing, we hear news of hackers penetrating highlysensitive financial and government institutions. There is an ongoingwar between the “good guys”, trying to bring to life the promise ofcomputer and Internet technology, and the “bad guys” using the same fornefarious purposes.
I too, was recently hit by a “phishing” attack. I received an e-mailfrom Bank of America Military Bank Online (so it seemed ). The e-mail spoke ofa modification to my account that, while innocuous, still required thatI log in to acknowledge the change. I browsed the web site; it appearedgenuine.
However, I never served in the military so I reported the incidentto Bank of America and was told they had received similar reports. The (authentic ) Bank of America web sitehad an FAQ on these types of attacks, including screen shots to helpspot phishing. Amusingly, a common indicator is spelling errors.
While my big phishing story was merely fodder for dinnerconversation (pun intended), it reminded me of the great need forconstant vigilance. Concern and curiosity led to a little research. Iinquired about my workplace for similar experiences and receivednumerous stories of stolen electronic identities, malware, morephishing attempts, etc.
I checked into some of the security tracking sites and discoveredsome alarming statistics. I learned there have been over 800 successfulhacker attacks on the Department of Homeland Security. According toCERT, in 2007 there were over 7,200 network vulnerabilities logged.
Many of these types of vulnerabilities can be prevented, and itlargely depends on how computer information systems are designed andimplemented. The problem is that developing and promulgating highlysecure systems is not easy, especially with our dependence upon legacysystems that have been around for years and were never designed withsecurity in mind.
But, in this age of innovation and automation, can't we inventsomething to solve these problems? If computers can fly (and land ) airplanes, drive cars,and fix a kitchen oven via the Internet, can't they help ensure thatthe software we develop is secure?
Yes, they can.
One promising solution comes from a relatively new branch ofsoftware development tools called static source analysis. In anutshell, a static source analyzer is a tool that examines softwaresource code and looks for defects that can result in security holes.
Much of the world's software uses programming languages – such as C,C++, and Java – that are a double-edged sword: while powerful andflexible, these languages also permit programmers to shoot themselvesin the foot.
Many of my fellow engineers regularly wrestle with a slew ofprogramming pitfalls: “uninitialized variables,” “buffer overflows,”and “race conditions”, to name a few.
The good news is that static analyzers can catch these flaws andreport them to the developer before the product is ever deployed. Thatis great stuff, you might think, but how does this help make a computermore secure? First, let's look at what makes systems vulnerable.
Hacking for Dummies
If you believe the stuff you see in the movies, you might think thathackers are a bunch of non-conforming geeks with green spiky hair whospend most of their time hanging out at techno dance clubs. Oh yeah,and in their spare time, they break into highly secure systems mostlyto play pranks or perhaps to “borrow” a few bucks to support theirwhirlwind lifestyle. The reality is a bit different.
While there is a fair share of rebels among hackers, many belong toorganized, well funded groups. They spend weeks developing ways tobreak into a particular system. Much of the work is drudgery, poringover thousands of lines of source or machine code. With the increasinguse of open source software, much of the code is readily availablemaking the hackers' jobs much easier.
While less glamorous than what Hollywood studios illustrate, thehacker's labor can result in something far more sinister than what yousee on the big screen. Instead of pranks, hackers are targeting thenation's power grid, the financial industry, and the most sensitivemilitary secrets.
An attacker tries some or all of the following:
Find a Back Door ” the hackerwill look for a way to get into a system through non-traditional means,for instance pretending to be another computer instead of a user. Oncea hacker breaks in, they may download a program that creates a passwordfor later use. In the process, the hacker hides evidence of thebreak-in.
Know the System Better than theDeveloper ” since large systems are often implemented byhundreds or even thousands of developers, portions of theimplementation will be less understood than others ” too many cooks, soto speak. A hacker doesn't need to understand the entire system ” onlythe most vulnerable parts.
Look for Paths Less Traveled ” every application or system has components that are used morefrequently compared to others that execute less often. The 80/20 ruleusually applies: 20% of the code runs 80% of the time.
That means 20% of the code is probably more reliable and secure.Conversely, the remaining 80% of less traveled code could be riddledwith security holes that go undetected for years. When it comes tosecurity, the aphorism “a chain is as strong as its weakest link”couldn't be more appropriate: all the hacker needs is one way in, and apath rarely taken is a fertile place to look.
Time It Well ” the hackerwho succeeds in breaking in will often get only one chance to strikebefore the attack is detected. Therefore, the attack must be carefullytimed.
|Figure1: Static source analyzer showing how two separate lines of code, whencombined, form a defect. Each line by itself is correct, but thecombination of the two produces a possible NULL pointer dereferencedefect. Source: Green Hills Software|
Hackers Meet Their Match
When it comes to the grunt work of understanding the source code andlooking for vulnerabilities, hackers have a bag of tricks known toexpose vulnerabilities.
Static source analyzers (Figure 1,above ) are designed to detect exactly the scenarios that arelikely to cause vulnerabilities, revealing them to the programmerbefore the system is released. By running the code through a staticanalyzer, hackers lose their one chance of a strike. In effect, anounce of static analysis prevention is worth a pound of cure against asuccessful attack.
These are some of the hacker's all time favorites, and the waysstatic analyzers battle them:
1) BufferOverflow ” Whenever a system needs to store a piece of data,like a user name, it needs to allocate a piece of memory, or a buffer.When the buffer is being filled with data (for instance a user types intheir login name), it is easy to go beyond the pre-allocated amount ofmemory, if a programmer wasn't careful.
That would make the system start reading or writing over some otherdata (like data that tell the system which code to execute next).Crafty hackers can this way insert a program of their own into thesystem. If their program gets access to the system, they can create newpasswords, and in the process hide the evidence of their break-in.
Solution: static sourceanalyzers are able to easily catch buffer overflows. They track theamount of allocated memory and look for accesses into the buffer. Whenthey detect a buffer access that is beyond the initially allocatedmemory, static analyzers report an error. This way the error is fixedwell before the system is released and exposed to hacker attacks.
2) BrokenInvariant (e.g. uninitialized variable) ” In languages like Cand C++, variables are constructs to create a state that the systemuses to make decisions. A program can have thousands of variables, andeach one needs to be explicitly given the initial value by theprogrammer.
If a programmer fails to give a variable an initial value that makessense to the system, the system may behave unpredictably. If the systemis behaving in unpredicted and untested ways, unforeseen security holescan quickly open up.
Solution: static analyzerskeep track of variables when they are initialized and with what values.Static analyzers can also distinguish if a variable is used just forits own value (in which case the value itself needs to be somethingexpected), or if a variable is used as a pointer to an object thatdescribes some more complex state (in which case the object that ispointed to and the variable both need to be something expected). Again,static analyzers can check for that.
3) ResourceLeak ” Ideally, a system is supposed to run forever. As one ofits fundamental functions, a system grants resources to applicationsrunning on a system. Resources like memory, disk access, accesses tomedia ports, etc. are limited by the hardware that's installed.
When resources are no longer used by an application (e.g. anapplication releases a resource or gets terminated), the system needsto “recycle” them for the next application that requests them.
If a programmer fails to instruct the system to reclaim theseresources, a hacker can create a vulnerable scenario where, forinstance, more and more memory is allocated until the memory pool isentirely exhausted. This often leads to “denial of service” attacks,because the system is busy looking for resources that are simply notavailable.
Solution: Static analyzerscan be customized to understand the types of resources a system cangrant. Systems will have different ways of allocating, using, andreclaiming resources ” also known as the API (Application ProgrammingInterface).
A static analyzer can ensure that a program's use of a systemresource can only occur after a resource has been allocated through aspecial API set of instructions. Also, a static analyzer can make surethe program releases the resource through the API instructions once itis no longer going to use it, thus preventing a resource leak.
4) StackOverflow – this vulnerability is much harder to detect, and canbe especially dangerous in today's multi-threaded systems. A functionstack is a piece of local memory that a program must have pre-allocatedin order to successfully run.
The biggest problem with function stacks is that the programmer mustknow how much memory to allocate when a new thread is created.Accurately computing that number can be difficult. What ends uphappening is that most programmers basically make an educated guess ofhow much memory is needed (and sometimes throw in a few extrakilobytes, just for good measure).
If this sounds like the wild west of programming, that's because itis. If programmers get this value wrong (i.e. too small), a functionstack of one thread of execution may corrupt a function stack ofanother and cause subtle, hard to reproduce bugs which are nearlyimpossible to find. Worse yet, they often slip through tests and QAprocesses making their way into the released code.
Solution: until recently,static analyzers had no way of battling this issue. What made thisimpossible to detect was that there was nothing wrong with the sourcecode, but with the interaction between the compiler (tool thattranslates source code into machine code) and the way a program wasstructured to execute. The solution comes in a new design of staticanalyzers, which integrates them into the compilers. This synergy ofstatic analyzers and compilers results in a whole new class of problemsthat can be detected.
Next in Part 2: ImplementingSecurity
As a Director of Engineering at Green Hills Software, Nikola Valerjevisresponsible for managing teams that plan, design, and develop newproducts, including the DoubleCheck static source analyzer.He also manages teams that evaluate new and existing solutions from theuser perspective. Mr. Valerjev holds a Bachelor of Science and a Masterof Engineering degree in computer science from Cornell University. Hehas been with Green Hills Software since 1997.