When I look at the exploits from the past few years related to implementations, I see that quite a lot of them are from C or C++, and a lot of them are overflow attacks.


Heartbleed was a buffer overflow in OpenSSL;
Recently, a bug in glibc was found that allowed buffer overflows during DNS resolving;


that's just the ones I can think off right now, but I doubt that these were the only ones that A) are for software written in C or C++ and B) are based on a buffer overflow.

Especially concerning the glibc bug, I read a comment that states that if this happened in JavaScript instead of in C, there wouldn't have been an issue. Even if the code was just compiled to Javascript, it wouldn't have been an issue.

Why are C and C++ so vulnerable to overflow attacks? 

C and C++, contrary to most other languages, traditionally do not check for overflows. If the source code says to put 120 bytes in an 85-byte buffer, the CPU will happily do so. This is related to the fact that while C and C++ have a notion of array, this notion is compile-time only. At execution time, there are only pointers, so there is no runtime method to check for an array access with regards to the conceptual length of that array.

By contrast, most other languages have a notion of array that survives at runtime, so that all array accesses can be systematically checked by the runtime system. This does not eliminate overflows: if the source code asks for something nonsensical as writing 120 bytes in an array of length 85, it still makes no sense. However, this automatically triggers an internal error condition (often an "exception", e.g. an ArrayIndexOutOfBoundException in Java) that interrupts normal execution and does not let the code proceed. This disrupts execution, and often implies a cessation of the complete processing (the thread dies), but it normally prevents exploitation beyond a simple denial-of-service.

Basically, buffer overflow exploits requires the code to make the overflow (reading or writing past the boundaries of the accessed buffer) and to keep on doing things beyond that overflow. Most modern languages, contrary to C and C++ (and a few others such as Forth or Assembly), don't allow the overflow to really occur and instead shoot the offender. From a security point of view this is much better.
