Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I recently read about the $subject.

Q: Why does a programming language has built-in trivial insecurity? Or.. it was just in the old times? How could this be?

share|improve this question

3 Answers 3

up vote 3 down vote accepted

C was designed at a time when available CPU power was a scarce resource, and there was much less programming done, also. Modern times have changed the context:

  • Nowadays, most of the computing time in a CPU is spent waiting for RAM, because CPU speed has increased much faster than RAM latency has decreased. So CPU have some "spare time" and thus can afford extra checks, e.g. boundary checks on arrays.

  • A lot more programming is done these days, which means that a lot more programmers are involved, and the average competence has then, mechanically, decreased.

  • Average attacker's competence, on the other hand, has quite increased. Buffer overflow exploits have gone, from the 1970s, from "theoretical weakness" to "generic attack which can be tuned automatically and scripted".

This is why almost all newer programming languages include inherent "protections" against buffer overflows, but also cross-typing attacks (when some bytes are made to be interpreted with a different type, e.g. making some code consider an integer as if it was a pointer) and memory allocation woes ("use-after-free"). For buffer overflows, the protection is twofold:

  • Newer languages offer automatic memory management, which allows for handling character strings as immutable values. This removes a lot of occasions for a careless programmer to allow a buffer overflow to occur.
  • Memory accesses are constrained to occur only with properly typed array objects, which enforce systematic checks on array bounds. When a buffer overflow occurs, an exception is thrown instead of letting the data actually overflow. This is still a bug, which can make the application crash, but this no longer allows arbitrary code execution.

Unfortunately, such protections cannot be generically backported to C. For instance, the C specification allows for writing out a pointer value into a file, and then, later on, reading it back -- and the pointer MUST still be valid. It is mathematically infeasible to write a garbage collector which can handle this case. There is a GC for C and C++, but (by nature) it cannot really support every "legal" C program.

In other words, if you "modify" C so that it is more robust against buffer overflows, then it no longer is "C", but something else (which you could call "Java" or "C#"). The original C is still used widely, sometimes for a good technical reason (e.g. to write code on a very small platform, like a smart card), but mostly out of tradition and for easier integration with all the existing libraries.

share|improve this answer

C is an simple language that's quite easy to translate back into Assembly / Machine Language (compared to modern languages) when you neglect optimizations.

C is not so much flawed with insecurities, its just C doesn't force you to always do things in a safer way like some other modern languages. A program running on a Bell Labs PDP-10 in the 1970s by skilled engineers had different requirements than a modern web server connected to the internet that may be attacked by skilled adversaries. Back then, you wanted the language to be fast and dead simple and so many simple sanity checks were left to the programmer.

One of the main 'insecure' parts of C is lack of bounds checking. If you want to copy a string of characters into a new array, the strcpy function will copy a string from one buffer to another buffer until it sees a NULL byte indicating the end of the first string. This allows buffer overflow attacks if you try squeezing 500 characters of input into a 256 byte buffer (the program will keep copying until it reaches the null character). The memory after that string may have had important data for the programs execution, possibly allowing an attacker to inject new machine level commands into the program. However, there are more secure ways to program within C, e.g., use strlcpy which takes as a parameter the size of the destination buffer and only copies up to that many characters (and then null terminates the string).

(Additionally, modern operating systems provide help through features like no-execute, no-write bits and address space layout randomization.)

Granted, its still possible for programmers to make mistakes.

share|improve this answer

When C was designed in the early 70s, it were different times.

  • Systems were usually only part of small, trusted networks or not networked at all.
  • They were rarely processing data from unknown sources
  • Hardware was slow and expensive

Due to these circumstances, high performance was a much higher concern than security. That's why C omits many sanity-checks on operations and expects that the programmers implement them themself when they feel the need for them and they can spare the resources it costs.

But nowadays, the situation has changed

  • It's hard to find a system which is not in some way connected to the internet
  • Systems frequently interact with untrusted or even anonymous users
  • Programs process information obtained from untrusted and potentially malicious sources.
  • Applications also become more and more complex, leaving more room for security-critical mistakes.

But on the other hand, hardware resources have become a lot more abundant. The greatest supercomputers from the 70s had a processing power which was several magnitudes below that of todays mobile phones.

For these reasons, the focus of programming languages has shifted from efficiency to security.

share|improve this answer

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.