It is virtually impossible to write software that is completely free of bugs.
Most bugs are benign causing mere annoyance, if they are even noticed. Others
can cause larger problems like data loss and lost productivity. The most severe
can lead to exploitation resulting in network compromise, denial of service and
theft of intellectual property or customer data.
Through my professional career I've learned important processes and practices to build security in to each
phase of the development process. I can apply these processes to your software
performing security audits of you code base, dynamic analysis and penetration
testing for your application.
Fun Exercise
Here's a simple program that reads each line from a text file and prints it to the screen.
What's wrong with this code?
#include <stdio.h>
int main(int argc, char* argv[]))
{
char copy[80];
char line[80];
static const char filename = "file.txt";
FILE* file = fopen(filename, "r");
if(file != NULL)
{
while(fgets(line, sizeof(line), file) != NULL)
{
strncpy(copy, line, strlen(line));
printf(copy);
}
fclose(file);
}
return 0;
}
Click here for the answer.
Error #1
First, line 16 introduces a format string vulnerability.
In this case external data (from the file) is passed to the printf function thorugh the format parameter without having first been sanitized. If an attacker
can manipulate the contents of the external file, they could insert specially crafted format specifiers that could be used
to compromize the application.
User controlled data should never be passed to any of the printf family of functions through the format parameter. The above line
of code should be rewritten as:
printf("%s", copy);
Error #2
Second, it looks like the programmer is taking great pains to avoid a buffer overflow vulnerability. First, the line is read
from the file using fgets, limiting the amount read to the size of the destination buffer. This is good! This line is then
copied into a different buffer. The programmer keeping the habbit of limiting how much is copied by using strncpy instead of
strcpy. This is good!
However, the programmer is using strncpy incorrectly. strncpy will copy from the source to the destiniation until the specified
number of characters are reached OR the NULL terminator is encountered. If the specified number of characters is reached, the
copy operation terminates and a NULL terminator is NOT appended to the destination. Using strlen(src) to limit strncpy will NEVER
NULL terminate the destination buffer.
In this instance, the copy buffer is left without a NULL terminator. When this is passed to printf, a read buffer overflow is
extremely likely. The code should be rewritten in such a way that the destination buffer is terminated properly. For instance:
int term = sizeof(dest) - 1;
term = min(term, strlen(line));
strncpy(copy, line, term);
copy[term] = '\0';