Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

There are many security risks coming from having close contact to the hardware as opposed to using well-tested and proved APIs from high level programming languages. It is much easier to cause a buffer overflow in C than in a language such as Java.

What are the risks or vulnerabilities (e.g. buffer overflows) that every C programmer should be aware of (I.E. vulnerabilities relevant to C programmers)? What problems could these lead to? How to avoid them, and what are common mistakes causing these to occur in programs?

share|improve this question
    
What about this list: owasp.org/index.php/Category:OWASP_Top_Ten_Project What more is needed than this? –  S.Lott Apr 27 '11 at 17:36
2  
@S.Lott: It seems to be very much about security issues in web development. There seems to be more resources on that in general than what I am actually asking for, it seems. –  Anto Apr 27 '11 at 17:37
    
@Anto: Please update the question to distinguish between all the resources on security and the security you're asking about. –  S.Lott Apr 27 '11 at 20:50
    
@S.Lott: I'm not sure what you mean. I ask for security which is of importance to most C programmers, that is, things like buffer overflows and other things which are possible in C. –  Anto Apr 27 '11 at 20:53
    
@Anto: "There seems to be more resources on that [web security?] in general than what I am actually asking for" Seems to say that you're asking about some security that isn't web security. True? If so, please update the question to explain what you're looking for. False? Then you are asking about web security, in which case, why isn't the OWASP list mentioned in your question? –  S.Lott Apr 27 '11 at 20:55

3 Answers 3

Buffer overflows are a big one. Nothing in C is range-checked by default, so it's very easy to overwrite a buffer. There's a standard library function, gets(), that cannot be stopped from overflowing the buffer, and should almost never be used.

There are some implementation-level techniques to hinder exploitation, such as scrambling heap blocks, but that won't stop buffer overflows in local buffers, which can often do interesting things like change the address a function will return to.

There is no good general solution in C. Many library functions have versions that will limit the amount they will write. although calculating that can be clumsy. There's software that can detect heap buffer overflows in test, as long as the appropriate test is run, and stack overflow will often show up as a crash in testing. Other than that, it's a matter of careful coding and code review.

A related issue is the problem of writing into a buffer too small by one character, forgetting that a C string that's n characters long requires n+1 characters in memory, because of the '\0' terminator. If the attacker can manage to store a string without the terminator, any C function expecting a string will continue processing until it hits a zero byte, which could result in copying or outputting more information than is desired (or hitting protected memory for a DOS attack). The solution, again, is awareness, care, and code reviews.

There's another risk with the printf() family. If you ever write char * str; ... printf(str);, you're setting yourself up for problems if str contains a '%' when printed. The %n format directive allows printf() to write into memory. The solution is printf("%s", str); or puts(str);. (Also, use the C99 snprintf() instead of sprintf().)

Using unsigned integers, particularly as loop indexes, can cause problems. If you assign a small negative value to an unsigned, you get a large positive value. That can undermine things like processing only N instances of something, or in limited functions like strncpy(). Examine all unsigned integers. You might want to avoid unsigned short, since a large value in one of those will convert to a large positive value in an int.

Don't forget that a character constant, in C, is actually an int. Writing something like char c; while((c = getchar()) != EOF) ... can easily fail, since EOF won't be representable in a char.

There's a lot more characteristic C mistakes I can think of, but these could cause security problems.

share|improve this answer
    
There's no need to use printf("%s", str) for a naked string when puts(str) will do the same job. –  Blrfl Apr 27 '11 at 20:22
    
@Birfl: Thanks, edited to include that. –  David Thornley Apr 27 '11 at 21:00
    
@Blrfl but puts appends a newline character while printf does not. –  rightføld Oct 28 '11 at 19:05
    
Could also do fputs(str, stdout), which doesn't. –  Blrfl Oct 28 '11 at 19:15

Here is an easy to miss risk that can cause problems which will take hours to fix.

Consider the following code, which will compile with no problems.

if(lpstr_current_state = CONST_EMERGENCY_STATE_HOLY_CRAP)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

When you check to see if lpstr_current_state is in CONST_EMERGENCY_STATE_HOLY_CRAP you're actually assigning. It is better to always put the constant variable on the left. When you put the constant on the left, then the compiler will fail because you can't assign a value to a variable.

if(CONST_EMERGENCY_STATE_HOLY_CRAP = lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

Then you can easily say to yourself, "Holy crap, that could have been bad", while fixing the code to read ...

if(CONST_EMERGENCY_STATE_HOLY_CRAP == lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}
share|improve this answer
7  
That is easy for a compiler to catch and flag as a warning, unlike some other problems. Unfortunately, not all compilers make it easy to do. –  David Thornley Apr 27 '11 at 17:36
2  
That can happen in languages other than C, any language that uses = and ==. –  FrustratedWithFormsDesigner Apr 27 '11 at 17:41
3  
This is also not really a security vulnerability, this is a bug. –  Chris Pitman Apr 27 '11 at 17:48
1  
These are called Yoda conditions. –  user11408 Apr 27 '11 at 17:51
2  
@Kristofer Hoch: If we're going to call any likely C bug a risk, and consider it here, we're going to need a much larger forum. –  David Thornley Apr 27 '11 at 18:23

Some of the C-specific risks include: buffer overflows, formatting string attacks and integer overflows.

share|improve this answer
    
There's nothing C-specific about buffer overflows - any language with pointers can have this. Integer overflows apply to just about any language, and can easily happen in managed code too. –  Steve Haigh Apr 27 '11 at 17:55
1  
@Steve, its not really pointers that cause that problem but how the language doesn't enforce array bounds. –  Doug T. Apr 27 '11 at 18:06
2  
@Steve the question was not asking about stuff that only concerns C, but something that C programmers should be aware of. –  AttackingHobo Apr 27 '11 at 18:16
1  
@Steve: C is unusually susceptible to buffer overflows, partly because of the lack of support for range-checking, and the number of library functions that will happily overflow buffers for you. –  David Thornley Apr 27 '11 at 18:17
    
I understand the question is asking about C in particular, but I think it is worth clarifying in case the answer is read out of context that these risks are more general. In particular developers of managed code are (IMHO) far too complacent about security, and integer overflows in particular affect most languages. –  Steve Haigh Apr 27 '11 at 18:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.