Intel Tool Helps SW Developers Develop More Secure Applications

There has been a steady occurrence of security breaches at prestigious companies over the last weeks, months and years.  These breaches are becoming far too frequent and, as the folks at Amazon and Zappos know, expensive.

A wide variety of ways exist for addressing these kinds of security challenges and Intel offers technologies to assist in the battle.  For probably the most sane and scalable way of addressing security issues, at least for enterprise applications, I would recommend that you jump over to Blake Dournaee's (Intel) blogs "Using a Service Gateway to Protect against the OWASP Top 10" and "How about a Security Layer?".  The idea of a Security Layer on a Service Gateway is truly the most comprehensive way to tackle these kinds security issues. 

Never-the-less, some enterprise shops may be unwilling to re-architect their legacy systems using the security layer approach and some developers are targeting client applications.  What tools and techniques can these developers use to mitigate security bugs?  For those developers I offer the following:

 I had a chat with Julian Horn, who is Intel's architect on the compiler team for the Static Security Analysis (SSA) tool.  SSA comes as part of the Intel compiler (C/C++/Fortran) and is available for Linux* and Windows*.  SSA identifies various coding errors such as memory and resource leaks, pointer and array errors, incorrect use of OpenMP* directives, and incorrect use of Cilk Plus language features.  SSA also identifies security errors such as buffer overflows and boundary violations, use of uninitialized variables and objects, incorrect usage of pointers and dynamically allocated memory, dangerous use of unchecked input, arithmetic overflow and divide by zero, and misuse of string, memory, and formatting library routines.

I was curious what kind of security flaws that SSA could find. Specifically, I wanted to know if it could help developers to mitigate any of the most dangerous software errors as identified by the Common Weakness Enumeration (CWE) community sponsored by Mitre.

After an email exchange with Julian, and pouring over the descriptions of the top twenty-five security bugs as reported by CWE, I determined that the Intel SSA could help to mitigate at least two of the top five errors listed.  Coming in at error number two is "OS Command Injection", and at number three was "Classic Buffer Overflow". How can SSA mitigate these errors?

Identification and Mitigation of CWE Top Error #2 (OS Command Injection)
OS Command Injection is an error type that really should be checked on both server and client side applications.  The essence of this error, or potential attack, is that, sometimes, your application is a bridge linking an outsider to the internals of your operating system. If your application simply passes un-trusted inputs to be fed into a command string that you pass to a system call, then your application can inadvertently wreak all kinds of havoc on the system. The recommended mitigation step is to validate all inputs to your application.

A simple minded BAD example, in "C", might be issuing a system call to delete a file that a user types in.

          // user inputs a filename to be deleted
          scanf (“%s”, str);                        // buffer overflow
          sprintf (cmd, "del %s", str);   // another buffer overflow
          system(cmd);                             // OS command injection, due to not validating the input

What happens if the user types into the input *.* rather than a normal filename?  Since the input has not been validated and was passed right to the OS, then clearly deletions unintended by the developer would occur. 

Analyzing your code for un-validated input is known as taint analysis – tainted input means un-validated input.  CWE recommends doing a taint analysis to identify where in your code you are not validating input, and then take steps to remove the taint.

Intel's Static Security Analysis tool uses a taint analysis algorithm to detect whether or not an unknown input has been compared against another value.  There are various rules under which taintedness is propagated from one variable to another.  One rule is that when a value is compared against another value this removes the taint.  If an untested value is used in a “dangerous” context, then you get an error reported by SSA.

The logic here is that a comparison is considered sufficient to sanitize the value.  The example below demonstrates the idea of tainted variable, x.  When x is used blindly with no comparisons done on it to check it validity, SSA flags this value as tainted:

          x = input;
          a[x] = 0;   // SSA identifies use of tainted value x

The example below uses a comparison operator to check the input value x, so it is considered untainted now by SSA:

          x = input;
          ok = (x < 10);     // comparison un-taints the value x
          if (ok) a[x] = 0;

This "good" example might still have some issues with it, the checking is not extensive, but at least the developer went to some effort to validate the input.

The key take away here is to use tools to find un-validated inputs and then add the necessary validation around each of these inputs.

Identification and Mitigation of CWE Top Error #3 (Classic Buffer Overflow)
Michael Howard & David LeBlanc, in their book Writing Secure Code, 2nd edition, identify the buffer overflow (AKA buffer overrun) as public enemy number one.  The Common Weakness Enumeration list is kinder, listing this issue as the number three most dangerous error.  It is well known that certain "C" functions are unsafe because they are vulnerable to buffer overflow attacks. These functions should be replaced with safe counterparts : strcpy, strncpy, strcat, and gets, among others. 

The buffer overflow terminology comes from the idea that if you continue to pour water into a finite sized container, the container will eventually overflow. In computer terms, the analogy means that copying too much text into a finite sized array, will cause the extra text in the buffer to spill over into areas of memory that the developer did not intend.  These areas of memory get corrupted with the excess text and malicious coders use this to exploit your application and potentially run malicious code within the confines of your application's process. I found the following buffer overflow example insightful, though I didn't want to copy it here in its entirety and will simply link to it instead.  It demonstrates how an overflow attack can occur and is found on an MSDN blog by Robert Horvick.

Other strains of buffer overflow can occur in some types of formatted input.  The biggest issue here is when the "%s" input format is used. This format specifier is generally regarded as unsafe. In the Intel Parallel Studio XE evaluation guide on Static Security Analysis (SSA), there is a nice example of SSA detecting a buffer overflow in a fscanf function. In this case, SSA indicates that it found an "unsafe format specifier," which is essentially a condition that can lead to buffer overflow.  The code snippet from this guide is as follows:

          // example that would allow buffer overflow  
          char data[255];
          fscanf(dfile, "%s", data);

          if (strcmp(data, string) != 0) {
                fprintf(stderr, "parse: Expected %s, got %s \n", string, data);

The call to fscanf uses an input descriptor string with a “%s” format specifier. This reads input characters up to the next newline and stores the data in the array “data”. There is no guarantee that the number of characters read will not overflow the bounds of the array, so this statement could corrupt memory.  SSA reported this as an error and the developer should follow up by making code changes using an alternative format specifier such as the "%255s"  to limit the number of characters read in.  The corrected code should be something like this:

          // example that corrects the undesired  buffer overflow  condition
          char data[255];
          fscanf(dfile, "%255s", data);

          if (strcmp(data, string) != 0) {
                fprintf(stderr, "parse: Expected %s, got %s \n", string, data);

For similar tips on how to protect your code through defensive programming, read this article by McGraw & Viega, Make your software behave: Preventing buffer overflows.

The key take away here, in addition to validating all  inputs, is to find unsafe “C” functions and format specifiers, and replace them with safe alternatives .

What should a developer do?
The security bugs discussed above are two of the most dangerous and prevalent according to CWE.  These bugs affect client applications that are run on laptops, desktops, ultrabooks, as well as enterprise applications on web servers, application servers, database servers and more.  Developers are urged to find these kinds of bugs using tools such as Intel Static Security Analysis, and then make it a practice to validate all inputs and to replace unsafe functions (strcpy, strncpy, strcat, and gets, among others)  with safe counterparts.  To learn more about steps you can take as a developer to reduce your exposure to security attacks go to the Department of Homeland Security's Build Security In website or visit the Common Weakness Evaluation site.

Oh, and did I mention that enterprise developers  should  jump over to Blake Dournaee's (Intel) blogs "Using a Service Gateway to Protect against the OWASP Top 10" and "How about a Security Layer?" to learn an even better way to secure your systems?

For more complete information about compiler optimizations, see our Optimization Notice.

Pour de plus amples informations sur les optimisations de compilation, consultez notre Avertissement concernant les optimisations.