Posts Tagged ‘buffer overflow’

Lint your code: Find probable mistakes much before testing

Monday, March 23rd, 2009

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Every programmer, no matter how great he is, makes mistakes sometime or the other while coding. Although every compiler tries its best to put across every possible error during compilation,many mistakes skip the wrath of compiler. Some are seemingly very innocent and very tough to be caught even during code review, sometimes even get through the cycle of testing. The real face of these mistakes show up always on the customer side by crashing the system.

Consider the following example:

int multiply(int m, int n)
{
	int result = 0;
	result = m * n;	
	return 	result;
}
 
void func()
{
	int m = 32767;
	int n = 32767;
	int result = 0;
	result = multiply( m, n );
}

Read the rest of this entry

© Safer Code | Lint your code: Find probable mistakes much before testing

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Improper Variable Initialization

Tuesday, January 13th, 2009

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Except for few good C programmers, others generally tend to ignore variable initialization or I should rather say “proper variable initialization”. Generally seen, the variable declaration itself is not done with a good thinking. Improper local variable initialization might not be good for the working of the program but improper global variable initialization might get your software or system hacked.

The uninitialized variable or a wrongly initialized variable might lead a program to change its normal course of flow from the intended one. For example: If a variable “index” is being used for array navigation and is left uninitialized, it might contain a garbage value which can lead to array index out of bounds error. or if the variable “index” is initialized wrongly to –1, it might lead to serious flaw in code flow. Even if an integer value is being initialized to ‘0’, it might lead to a security check bypass because for some programs, even a ‘0’ is considered a valid value.

Lets take an example of a code piece.

 int isMachineRunning = GetMachineStatus();
 int state = GetUserState(isMachineRunning);
 int userid = 0;
 if (state) {
	userid = ExtractUserID(state);
 }
/* do stuff */
if (uid == 0) {
	DoAdminThings();
}

Continue Reading >>

© Safer Code | Improper Variable Initialization

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Unsafe Functions In C And Their Safer Replacements: Strings Part II

Tuesday, December 2nd, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Last time, we advised you to use ditch the unsafe functions like strcpy and strcat, and use their safer replacements (strlcpy, strlcat) instead. However, there is a small problem with this that you might discover that your compiler (especially gcc) does not have these functions in their implementation of the c library (libc). Why is this so? Read this thread about the original patch that was submitted to add these functions to libc. Essentially, it was rejected on the basis that these functions hide problems instead of solving them and would actually lead to hard to detect bugs that creep in because of unsolicited truncation caused by these functions. A sample implementation of strlcpy looks like this:

#include <sys/types.h>
#include <string.h>
 
/*
 * Copy src to string dst of size siz.  At most siz-1 characters
 * will be copied.  Always NUL terminates (unless siz == 0).
 * Returns strlen(src); if retval >= siz, truncation occurred.
 */
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
	char *d = dst;
	const char *s = src;
	size_t n = siz;
 
	/* Copy as many bytes as will fit */
	if (n != 0) {
		while (--n != 0) {
			if ((*d++ = *s++) == '\0')
				break;
		}
	}
 
	/* Not enough room in dst, add NUL and traverse rest of src */
	if (n == 0) {
		if (siz != 0)
			*d = '\0';		/* NUL-terminate dst */
		while (*s++)
			;
	}
 
	return(s - src - 1);	/* count does not include NUL */
}

Now, there are supporters for both the sides. Solaris and BSD accepted these functions while GNU/Linux refuses to do so till date. The stand that I’d like to take here is that this is at least a step towards the right direction because a truncation bug is much better than an attacker taking over the control of your network just by pushing out a long string onto the stack. However, we could indeed augment the implementation above to communicate back to the caller somehow that truncation occurred. Whichever side you choose, be aware that these problems are very real and don’t just keep on using the older unsafe versions (Even in words of Ulrich Drepper, the opposer of strlcpy: “ The users of these functions[strcpy, strcat] should be severly punished”).

© Safer Code | Unsafe Functions In C And Their Safer Replacements: Strings Part II

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Validating Untrusted String Inputs

Tuesday, November 11th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Alright!! In my last post about untrusted inputs, we talked about validating the data of the “integer” input parameters, checking the out parameters et cetera.This time, we’ll talk about other types of inputs. If you have written a program to take in multiple lines of strings as an input from the user, you need to make sure that the input is not tainted. It is clean and as per your expectations. For example: If your program requires an answer for a question which can be subjective, then you need to provide a string buffer good enough to get a complete answer but not large enough to crash your system or make it run out of memory. Or you need to protect your system from getting any malicious scripts being inserted.Strings are a very risky area for inputs as there is pre-defined rule for this type of validation. So, following are the points to ponder to make your code safe and secure.

  1. Firstly, do use regular expressions to validate the string input. For example, ^[A-Za-z0-9]+$ specifies that the string must be at least one character long and that it can only include upper-case letters, lower-case letters, and the digits 0 through 9 (in any order). You can use regular expressions to limit which characters are allowed and to be more specific (for example, you can often limit even further what the first character can be).If you use regular expressions, be sure to indicate that you want to match the beginning (usually symbolized by ^) and end (usually symbolized by $) of the data in your match. If you forget to include ^ or $, an attacker could include legal text inside their attack to bypass your check.
  2. Now, if your program needs more variety of input and the above point doesn’t fulfil the requirements then you need to make a bit more complicated regular expressions. If the data is a filename (or will be used to create one), be very restrictive. Ideally, don’t let users choose filenames, and if that won’t work, limit the characters to small patterns such as ^[A-Za-z0-9][A-Za-z0-9._\-]*$. You should consider omitting from the legal patterns characters like “/”, control characters (especially newline), and a leading “.”Similarly, you need to take care for email strings, locale specific strings. UTF-8 encoding characters et cetera. In most of the programs, complex regular expressions are good enough to validate a string. But in certain cases, a malicious input containing some script code can spoil the fun.
  3. If your program faces HTML tags or script related instructions in the input, the input should be rejected immidiately or your program might get infected with self executing malicious code. This technique is generally used in Cross Site scripting attack. (XSS attack). These problems are especially a problem for Web applications. Now, you need to again take care not to validate any input which looks like an HTML tag. The easiest way is to use above mentioned regular expressions which won’t allow the entry of ‘<’ or ‘>’ character. But if you must support some of the HTML tags like <a href=> etc, please validate them exclusively by filtering the whole string using a regex like ^(http|ftp|https)://[-A-Za-z0-9._/]+$. A pattern that allows some more complex patterns is: ^(http|ftp|https)://[-A-Za-z0-9._]+(\/([A-Za-z0-9\-\_\.\!\~\*\'\(\)\%\?]+))*/?$
  4. For more complex strings, like reading a data file, regular expressions, again, prove useful but the ideal way is to break the file into multiple chunks rather than reading it in one complete string.

To Keep your String input kept in well defined range or buffer, make sure that your program terminates it with a NULL character. This will ensure that even if a large buffer is inserted using the input, the sting will get truncated as soon as the buffer gets full and it will be protected from buffer overflow.

© Safer Code | Validating Untrusted String Inputs

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Unsafe Functions In C And Their Safer Replacements: Strings Part I

Tuesday, November 4th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

A string is a fundamental part of programs all around us. Data exchange in many forms happens in strings (e.g. user input, command line arguments, web forms, text protocols and what not.) But most programs written in C are plagued by security issues because of their usage of unsafe functions. A string is not a built-in data type in C, instead it is termed as a continguous sequence of characters terminated by a NULL character (‘\0’). Now, many of the “standard” string manipulation functions written in early part of C development took this definition by heart, assumed that a programmer always knows what he is doing (though I agree that this MUST be true), and put out a code meant to be used in an everyone-is-good world. Subsequently, the shortcomings were noticed, stronger sibling functions were created but the older ones are still supported because they are “standard”. This means that naive programmers continue to use them and put their programs’ security into jeopardy. This series will do an in-depth analysis of such unsafe functions, tell you why they are unsafe, and bring out what alternatives you have in-built and what alternatives you can create.

Our first candidate is the very famous “strcpy()”. Lets see why it is unsafe.

(more…)

© Safer Code | Unsafe Functions In C And Their Safer Replacements: Strings Part I

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Validating Untrusted Integer Inputs

Tuesday, October 21st, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

If you are writing a software which exposes APIs to be used by a third party, then first thing you have to do is to make sure that all the integers parameters have been validated. Every incoming value to your function should be considered as tainted. The function should validate the input value by checking it for all possible malicious value. After the function validates the input, then only any operation on the input value should be performed.

Consider the following code sample:

void func( int size )
{
 char* str;
 
 if(size &gt; 0 )
 {
  str = (char*)malloc(size * sizeof(char*));
  size++;
  /**
  *some code to operate on this string "str"
  **/
  free(str);
 }
}

I am sure that by now, you would have identified some loop holes in this code. Now, a caller of this function can give different input values which might result in following flaws:

1) The function might get an highest input value which results in a large memory allocation for ‘char* str’ which the function never expected.
2) The function might result in memory allocation failure as there is possiblity of the system running out of memory.
3) The function might have an overflow issue due to an increment in input value which could have been equal to SIZE_MAX.
These scenarios might serve as a boon for a hacker and he/she can instigate either a denial of service or any other buffer overflow errors.

Now, Lets rework the above depicted code again.

#define MAX_SIZE_OF_STRING ( 100 )
void func( int size )
{
 char* str;
 
 if(size &gt; 0 &amp;&amp; size &lt;= MAX_SIZE_OF_STRING)
 {
  if(str == null)
  {
   str = (char*)malloc( size * sizeof(char*));
   if(size &lt; SIZE_MAX)
   {
    size++;
   }
   /**
   *some code to operate on this string "str"
   **/
  }
  if(str != null)
  {
   free(str);
  }
 }
}

Please try to notice few defensive points from the above given code.

1) We have defined a maximum size for the string. We need to do this to make sure that large chunks of memory do not get allocated. This will result in optimized memory usage and longer life of the program.
2) We have validated the input value for its range comparing against its minimum and maximum value. By doing this, We sufficed the purpose of defining the size of the string.
3) Again, we check the input variable size for its value less than SIZE_MAX (maximum value possible for an integer). By doing this, we safeguarded against an overflow. Now, the size variable can never incremented beyond the maximum value.
4) Checking for ’size > 0′ helps in making sure that non zero number of bytes are allocated in memory, in turn, saving us from memory corruption.

By adding extra defense checks or safeguards, you might contribute towards addition in code size. But isn’t it better to have a secure code rather than less code which is vulnerable to exploits.

The point I am trying to make is very simple and is not a great deal. Everyone of us know of it but we tend to ignore these minor things resulting in misuse of code. Keeping these small points in mind while coding and adding these defense checks or safeguards will definitely result in robust and secure code.

© Safer Code | Validating Untrusted Integer Inputs

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below