Why Developing in Rust Can Help You Avoid Security Pitfalls
In this blog we explore some of the common issues in the current coding landscape and why Rust can reduce human error and help us write safe and secure code.
We all depend on software every day of our lives—whether using our personal devices, TVs or even fridges and washing machines. We depend on software for our financial, personal and psychological safety, but as consumers it’s little more than a "black box" to us—we see the user side of things, but never get access to the source code.
Despite data breaches making regular headlines, we still trust large organisations to manage our information safely and securely, and indeed, they have a duty of care to us and our data.
For our world to get safer, we need senior stakeholders to understand the importance of secure-by-design and how that mindset can not only protect their customers, but also their own reputation, and indeed bottom line, where laws and regulations such as GDPR are starting to bite.
Rust could prove a vital step towards safer businesses.
Why Do Breaches Occur?
For all the safeguards and regulations in place, breaches are still impossible to stamp out completely, and the three main reasons tend to be:
- User error. Avoidable but still inevitable. Employers must train staff and maintain high levels of competence.
- Phishing attacks. Closely related to user error, these are mechanisms that the bad actors use to get somebody on the inside of an organisation to trust them, and to give them access to information to which they should never have access. Again, these "soft" attacks must be mitigated by mandatory employee training.
- Product design weaknesses. This might include poor infrastructure design and security, but are most commonly in the poor standards of software design and development. This is where Rust can help massively.
Most software is hierarchical. Developers do not write every piece of software that a solution requires; they develop the smallest amount possible and import external libraries wherever possible for the rest to avoid rewriting vast swathes of code themselves. This makes financial and commercial sense as companies can get products to market quicker and for lower cost. This seems like a win-win but the downside is that you have no control over the quality of the libraries that you import. Security tools can be used to scan for vulnerabilities in these libraries, but vulnerabilities can generally only be detected when they’ve already caused lots of damage to the rest of the world, and therefore have become visible and have "signatures" developed to detect them. This means that there are a huge number of vulnerabilities that are yet to be detected—these are known as zero-day vulnerabilities.
Memory Safety Issues
The libraries usually provide functionality that is close to the operating system (or indeed part of the operating system), or need to be fast; and as a result, the bottom layers of libraries are almost always written in C or C++. Both these languages are solid, fast languages that can give the required performance, but they do not protect developers from making mistakes in their code.
Many of these mistakes are not just logical mistakes that could be seen easily, but more often they are memory management related bugs that allow bad actors to coerce the software to do things that it was never designed to do. Often, this is to extract information that the software would be processing. Indeed, in some cases, the bad actor can cause the software to directly manipulate the production database, extracting information that can be sold on the black market, or allowing the bad actor to alter data that is stored in the database.
Microsoft security engineer Matt Miller recently said that nearly 70% of all bugs in Microsoft products were memory safety issues. In conventional Rust code, these vulnerabilities are virtually impossible to create.
The Benefits of Rust
In Rust, it’s almost impossible to accidentally create vulnerabilities that would allow bad actors the necessary access to manipulate or extract data.
We know, though, that much of the low-level library code would be written in C or C++, both of which would allow this kind of bad code. This is where Rust is invaluable, because large amounts of the standard libraries and operating system level code is being rewritten in pure Rust. This means that the amount of code that could contain vulnerabilities is potentially far smaller for Rust than for any other language.
Rust has a strong type system
The next huge benefit is that the type system in Rust is very strong, and the language is designed to allow developers to use it to make invalid states completely unrepresentable. This means that logical errors in Rust software can be prevented from ever reaching production systems, and the Rust compiler can prevent code changes and enhancements from ever introducing logical errors.
The cost benefits of fast-running code
Code written in Rust compiles to some of the fastest running code in the industry with some of the smallest memory demands. Fast-running code is financially cheaper to run as you can run it on slower/cheaper hardware, or you can support a much larger number of customers on the same hardware. Also, the user experience is better, as the response times are far quicker, and this also gives a benefit with Google PageRank for websites resulting in much improved rankings in Google search results.
Code reliability and safe design mean consumer savings
Your mortgage or loans are held in databases, and managed by software. Your bank balance is data that is manipulated by software. Your online purchases and credit card transactions are processed by software. In theory, if any of this software has a vulnerability that could be abused by a bad actor, your bank could be emptied, you could find court orders for lack of payment of loans that aren’t in arrears, products you paid for could be sent elsewhere, credit card details could be stolen, or even your identity could be stolen.
Why Doesn’t Everyone Develop in Rust?
Rust is hard. No, really, Rust is very very hard to learn.
Many modern software developers often get into software development as a safe career choice that pays reasonably well. They often choose an easy language as a starting point, maybe PHP, Python or Java, and most businesses will hire the cheapest developers they can to keep costs down, which usually turns out to be a false economy.
Software development is often seen as a common and relatively simple skill, and developing simple software to a poor standard is indeed, quite easy. The problem is that employers can’t always tell the difference between simple and complex tasks, and they can’t easily predict the hidden costs of poor software development standards. They might take on a junior software developer and expect them to handle any task, just maybe a little slower. They then might promote developers within their organisation for working long hours rather than their skills.
This matters. It matters because managers might have little or no knowledge of security issues and vulnerabilities, or performance issues. Money is thrown at hardware to deal with performance issues because it’s just assumed that the software needs more processing power, when often it is just very inefficient code, badly designed by people who have had no training to know better. Worse, the vulnerabilities that are written into the code are for similar reasons, but are far less obvious. This means that huge chunks of software that exist in this world are ticking time-bombs, just waiting for bad actors to discover some weaknesses and exploit them.
Rust could mitigate many of these issues, but if these developers struggle with the basics in a simple language, then realistically, they have no chance of getting to grips with the complexities of the Rust language.
Is Rust on the Rise?
Despite the dedication required to learn it, Rust has topped the most loved language on StackOverflow for six or more years now. Clearly Rust is doing something right, especially as major organisations such as Microsoft, Amazon, Google and CloudFlare are committing heavily to Rust specifically to help mitigate security risks in their software. They are often using Rust for core and critical systems to minimise security flaws at the same time as maximising the execution speed of their software.
The big struggle is navigating the chicken-and-egg situation that is finding enough skilled Rust developers. Without enough demand for skills, there are very few candidates. Without the candidates, many projects that might have been developed using Rust are falling back to languages that have a much larger candidate base, which again brings us to false economies.
When a company believes that the number of developers they have dictates the rate at which they can develop and release products, they really misunderstand the costs of poorly developed code. One highly skilled developer can produce fast, reliable, secure and stable solutions much faster than a team of many junior developers, simply due to the years of experience recognising and avoiding pitfalls. The senior developer will know how to plan and deliver the design in a progressive way that leaves the fewest blockers on the path to completion, while the junior developer might be more likely to randomly pick parts that they believe they might be able to write, hoping that someone else will pick the harder parts. This could result in a random collection of disordered functions that won’t work together at all, tied together with nasty bodges to try to get things to work. It’s a recipe for security vulnerabilities, atrocious performance issues, and functionality bugs that will result in the need for large amounts of ongoing maintenance and fixes.
How Businesses Can Take Steps Towards Rust
The development of safe and attack-resistant software is critical to all of our lives, and we’re constantly at the mercy of the quality of the software that we use without even really thinking about it. This is why those of us who can influence software development practices have a duty to do what we can to minimise these risks—and there’s no better start than to push for software to be developed in a highly secure and attack-resistant language such as Rust.
If you’re running a business of any significant size that involves software development, then you really need to build a thorough understanding of the false economies relating to developer abilities, vulnerability risks, and the infrastructure costs of patching over poorly performing code.
Despite how demanding it can be to learn, Rust is increasingly looking like the right tool for the future. It’s the right tool to keep our bank accounts safe, our identities from being stolen, and our interactions with websites from being interfered with. More and more core services are being rewritten in Rust by major IT companies, and I hope that the rest of the industry will start to become aware of these risks, and the benefits that Rust can bring. The investment is significant, the learning curve is steep, but we need Rust in our lives, even if we never see any of it directly ourselves.
If you’re currently considering addressing this issue in your organisation, it might be worth looking at any new projects with Rust-tinted spectacles. Maybe try to get a single, highly experienced and skilled developer to start developing a solution in Rust, and see how it goes. Then, over time, you might find that you can start to migrate more and more of your codebase to Rust, and ideally to a small highly skilled team of developers to maintain very high standards, rather than a large team of less experienced developers with all of the associated hidden costs.
If you want to know more about Rust, or how you can help embed a coaching culture in your company that supports learning new coding languages and practices, reach out to Contino.