Premature optimization is the enemy of security

We read continually about new buffer overflows in tools that allow ‘bad guys’ to take over various systems. This week the unfortunate program was Avast AV. The bit that always surprises me is that these issues are still occurring in code written relatively recently. We’ve known how to fix all these issues for many years, yet people keep writing code that has these defects. I’d argue that the main cause of this is premature optimization and ignorance.

If we take a ‘typical’ buffer overflow in a ‘low level’ language like C++

char a[4];
// Write past the end of the buffer
strcpy(a,"a string longer than 4 characters"); 

A basic example – but this has been solved for years.

  • You could use any number of ‘String’ objects such as the std::string, Microsoft CString or QT QString have automatic memory management.
  • Alternatively you can move to a higher level language with memory management like Python,C# or Java where such issues don’t occur at all (except in the underlying libraries they use – which are often written in low level languages!)
  • Or if you really must use low level constructs you can write this safely, with lots of bounds checking

However time and again such problems are found in code, and time and again they cause security issues. So why does it happen? I’d argue premature optimization is the root of this. An awful lot of code is written in languages like C/C++ because it’s ‘fast’ – when in most cases it would be better that it be safe.

It’s interesting to see Google Tensorflow encourage users to write a lot of the high level logic in Python (a nice safe language), while keeping the hard computations in native code. This reduces the attack surface of any solution built on it, allowing a nice play off between speed to develop, safety and speed to run.

We should all learn a lesson from this:

  • Always pick tools (languages/frameworks) that do security for you
  • Only write your own and optimize if you really need to
  • If you write you own, be prepared for all the extra testing (functional and security) you’ll have to do to make it work

If we go back to Avast’s case – AV software does have to be fast, so they may need to write this logic in C/C++. But they could have used safer objects (such as stdlib Containers), or they could have just written it safely, but they didn’t and as a result, turned a piece of security software into a remotely exploitable attack vector. The security industry can, and must do better.