Developers are undoubtedly on the front line when it comes to securing software. They write the operating systems, the services and the applications that power our connected world. The smallest, most innocent mistake on their part can have a devastating impact on both service providers and end users.
Mistakes can find their way into production environments from a variety of sources. This is as true for the open source community as it is for major corporations with practically endless resources.
In this post I propose that the software development community should work on developing and then standardising security-related libraries that focus on what the developer is trying to achieve – their intent – rather than asking dozens of questions about how they want to achieve it. I also provide a case study to show the reader a concrete example of the kind of approach I’m proposing, along with the benefits it has provided in that case.
The fragmentation of software expertise
Software errors often happen when we require inexpert developers to make expert decisions, and we can’t expect all developers to be experts in all areas. The information security community will often counsel that security is the most important aspect of producing software, but for developers – professional and amateur – this matter is not so settled. Given the innumerable priorities and incentives we’re handed by management and users, taking the time to learn and implement security best practices won’t always come top of the list.
In any case, achieving this expertise is an ongoing and expensive commitment, even for professional software developers already in the industry, let alone the hobbyist developer releasing their first mobile application onto an app store.
Developers of all stripes will continue to make applications available to countless millions of end users. And even if high quality, freely-available tooling is in place to help them, we can’t oblige them to use it. In other words, inexpert developers will continue to make inexpert decisions regarding software security.
This situation would be greatly improved if all developers were offered the same simple options, presented in terms of their application-level goals, and not in terms requiring particular security or cryptography expertise to fully understand.
Case study – resource leaks
A major area of complexity and risk facing some developers is resource leakage. Anyone who has made serious use of languages with manual memory management will be familiar with the pain of seeing your finite resource being frittered away by an application – and the often greater pain of debugging such an error.
Millions of developer hours have been spent creating novel, high-quality static and dynamic analysis software. But the underlying problem remains: despite all the support available to developers, software is still released with memory leaks. And if adversaries can trigger leaks, we have a security issue, as they will likely be able to crash or degrade our application in a denial of service attack.
The issue of resource leakage has been taken very seriously by members of the C++ standardisation community. After much discussion, experimentation and even some false starts, the C++ standard library now has ‘smart’ pointers representing the higher-level semantics of resource “ownership”. In this model, ownership of valuable resources, such as memory, implies responsibility for ensuring that those resources are freed for others to use. Smart pointers provide two major sets of ownership semantics:
-
Unique ownership: when I am done with the smart pointer the resource is no longer required.
-
Shared ownership: when I am done with the smart pointer, check whether other owners are still using the resource and free it when we’re all done.
Proper use of these smart pointers allows us to automate the process of freeing resources at the appropriate time, simply by tagging them with the desired ownership model. This is a great example of focusing on the developer’s intent – the outcome that the developer is seeking – as opposed to the mechanics of how the intent is achieved. The ‘what’ rather than the ‘how’.
The developer’s intent
The memory management parable isn’t an isolated incident. Many languages are introducing support for higher level abstractions as a way of addressing systematic problems in software development – concurrency, for example.
Focusing language and standard library features on the developer’s intent frees developers from the requirement to become experts in every one of the many fields they’ll encounter while building even a simple application.
The idiomatic and recommended way of generating a random number in some languages is surprisingly complex, leading even experienced developers to vent, “I just wanted to roll a dice! What’s a Mersenne Twister?”.
In software security this is highly analogous to:
“I just wanted to store a user’s password! What’s a salted hash?”
“I just wanted to send data to another endpoint! What’s a public key?”
These are exactly the kinds of speed bumps that lead even the most diligent developer to reach out to their favourite search engine or online “Q&A” community for help. These sites are often excellent for overcoming very specific problems, but their answers naturally lack context. These are ‘minimum viable solutions’ with little or no regard for security, performance or other nonfunctional requirements.
Call to arms
The software development community (you, dear reader!) can have a large impact on the problem of developers committing security mistakes by creating and popularising the language and standard library features that allow them to achieve their goals, without becoming an information security expert. With these in place, code that builds and runs must necessarily be secure: even trivially incorrect usage would raise an error that could not be ignored.
So, what’s the call to arms? Contribute! Does your favourite language have standardised, well-documented security features matching the high-level outcomes that developers are seeking? If not, is there a third-party library that looks promising? Why not look to get that standardised?
In my experience, the reason that security-related features aren’t in standard libraries is not down to a lack of interest. It’s another case of the problem described above: expertise in one area (for example, formal language specification) does not imply expertise in security best practice.
We have to work together. If you can produce a straw man for people to evaluate and improve, you might be surprised at the response you get from other developers with exactly the same aims.
Dan S
Software Technical Lead
Source: National Cyber Security Centre