You’ve run every software composition analysis tool, you've statically and dynamically analyzed your code, and maybe you've even pen-tested it before deployment. If there’s anything else to consider as far as software security is concerned, you don’t know about it.
And yet, despite these efforts, you know that many other projects have done the same things, and still dozens of new vulnerabilities are discovered every day. You wonder, Did we do enough? Is there ever enough? If you’re starting with an unsafe programming language, the answer is no.
Many developers don’t have the years of secure coding experience necessary to develop secure software using traditional programming languages such as C and C++. This lack of experience, combined with tight deadlines and budget limitations, results in code that is likely vulnerable to attack – a major reason why 49% of codebases containing open-source software have high-risk vulnerabilities.
Luckily, developers aren’t stuck with insecure, unsafe programming languages when developing new applications. Start off with safe languages to add another dimension of security that drastically reduces vulnerabilities in your systems and applications. Here is a rundown on the languages and packages that are most secure.
The perils of unsafe programming languages
When it comes to security, not all languages are created equal. Many make additional security demands on already harried developers. Languages such as C and C++ give developers flexibility without considering security. Programming elements such as memory, threads, and variable types can be manipulated in any shape or form, making the languages very powerful but also susceptible to cybersecurity attacks.
These inherent design features or lack of safety mechanisms can contribute to nasty vulnerabilities such as:
- Buffer overflows: These occur when data exceeding the capacity of a buffer is written into it. This can overwrite adjacent memory locations, potentially allowing an attacker to execute arbitrary code or even causing a system crash.
- Null pointer dereferencing: When a null pointer is dereferenced (used to access memory), it can lead to undefined behavior, including potential system crashes. In some scenarios, attackers might leverage such incidents to execute arbitrary code.
- Format string vulnerabilities: These arise when an application does not properly sanitize user-supplied data used as format strings. An attacker can manipulate format strings to read the stack or even to execute arbitrary code.
- Type confusion: This vulnerability surfaces when a program treats an object of one type as if it were one of a different type. It can lead to logic bugs or crashes, or it can be exploited to execute arbitrary code or bypass security checks.
- Memory vulnerabilities exposed in code created with unsafe languages can be particularly nettlesome. According to ZDNet, nearly two-thirds of vulnerabilities in the Linux kernel, 70% of vulnerabilities in iOS and macOS, 70% of all CVEs at Microsoft, and 90% of vulnerabilities in the Android OS stem from memory safety issues.
The merits of safe programming languages
Safe programming languages, on the other hand, are designed with security in mind. Rust, for example, is a statically typed, compiled language designed to be memory-, type-, and thread-safe with a goal of eliminating entire classes of vulnerabilities that are common in other languages. The program simply won’t compile if any of these problems exist.
Rust uses a borrow-and-ownership system to ensure that memory is always accessed in a safe and predictable way. It includes several other features, such as lifetime checking and a borrow checker, to further improve memory safety.
Rust is also fast — almost as fast as C and often quite a bit faster than C++ — so it can eliminate memory vulnerabilities without a significant performance tradeoff. It also has a powerful suite of developer tools, another feature contributing to the popularity of the language.
Rust isn’t the only safe language. Ruby is also considered safe. It has a built-in taint tracking system that allows developers to distinguish between safe data and untrusted data that could be used to perform malicious actions. The language also has a restricted execution mode that allows developers to run untrusted code in a safe environment, preventing it from accessing sensitive data or performing dangerous operations.
Like Rust, Ruby is a strongly typed language. The types of variables and expressions are checked at runtime, which helps prevent errors and security vulnerabilities that can occur in weakly typed languages, such as JavaScript, PHP, and Perl. Also, like Rust, Ruby has a large and active community of developers who are constantly working to improve the security of the language.
Safe programming languages often include many other security features such as support of pure functions, which prevents them from modifying the state of the program, making them more difficult to exploit; design by contract, a technique for specifying the pre- and post-conditions of methods, which can help prevent errors and security vulnerabilities by ensuring that methods are used correctly; and robust exception handling, which can prevent errors that cause a program to crash.
Safe programming languages make the difference
While safe programming languages are considered more secure than unsafe languages, no language is completely secure. As such, it's always important to follow secure development practices when creating applications.
Nevertheless, the choice of programming language can make a substantial difference, and the use of open-source components written in a safe programming language can significantly reduce the risk of vulnerabilities in an application and enhance the security of an organization's software supply chain.
While no language can make a system entirely immune to attacks, languages such as Rust offer built-in mechanisms that help mitigate common vulnerabilities at compile time. The journey to secure open-source components involves more than just tooling; it requires a robust understanding of the languages in use, their inherent security features, and potential weaknesses.
Secure software starts with trusted developers and secure code. Embracing safe programming languages is one significant step toward achieving the goal.
Keep learning
- Get up to speed on securing AI/ML systems and software with our Special Report. Plus: See the Webinar: The MLephant in the Room.
- Find the best building blocks for your next app with RL's Spectra Assure Community, where you can quickly search the latest safe packages on npm, PyPI and RubyGems.
- Learn how you can go beyond the SBOM with deep visibility and new controls for the software you build or buy. Learn more in our Special Report — and take a deep dive with our white paper.
- Commercial software risk is under-addressed. Get key insights with our Special Report, download the related white paper — and see our related Webinar for more insights.
Explore RL's Spectra suite: Spectra Assure for software supply chain security, Spectra Detect for scalable file analysis, Spectra Analyze for malware analysis and threat hunting, and Spectra Intelligence for reputation data and intelligence.