There is a discussion about the security of applications written in C on Hacker News recently after the report of HeartBleed bug in OpenSSL. In this discussion, some people are saying that the applications written in C are unsafe. It seems all or most of the faults should be laid on C. I think this is biased. The language itself should not be blamed.
Safety is a relative term for programming languages. No language is absolutely safe. We claim some languages like Java and C# are safer than C/C++ because they have memory protection mechanism built in, we cannot access arbitrary memory locations in applications written in Java and C#. That's true. However, with great power comes with great responsibility. As a developer, while you can jump around memory locations with pointers in C, you should look after your baby yourself as well, if you are not confident in how to handle the potential memory leaks in your applications, you should seek help from your colleagues or run more tests and adopt strict code review process. If you put all your hope for handling all security issues on the language itself, you are wrong.
Safety is not the only criteria to consider about when you decide which language to choose. In some systems, we have to use languages like C to ensure its performance and efficiency. We need to strike a balance between performance and safety. Yes, we can use Java to implement SSL libraries(we do have) and use them to achieve the SSL/TLS communication, but since SSL communication requires much resource due to complicated handshake process and data encryption and descryption, in some systems, the library implemented with Java will drag down the performance dramatically. In contrast, with C, we will expect that our performance is not much affected and at the same time gain the safety we the implementation is carefully crafted.
Let's get back to the HeartBleed bug. The bug is that the payload length is never actually checked against the size of the request packet. Therefore, the memcpy() can read arbitrary data beyond the storage location of the request by sending an arbitrary payload length (up to 64K) and an undersized payload.
The issue itself is caused by the lack of check on the input payload length at the first place. The developer is not careful enough to check the input payload length from the client. We should never trust user input. Of course, if the language itself has the mechnism which restricts the data to be read, it will still be able to save the case even if the payload length check is bypassed. Anyhow, the first fault is caused by the implementation.
To say some more, we should take code review seriously when writing programs. Especially in such important projects which used by many organizations and projects, let's consider if there is a strict code review process adopted, this kind of bug should be able to be identified before release or at least should be identified long before it causes any damage. There is a doubt now whether OpenSSL development team adopts the strict code review process or not.
In conclusion, we, the programmers, should be the one to guarantee the safety of our applications, not the language we use.
In languages with array bound checking this kind of bug cannot happen.