Introduction
Rust is a programming language created in 2015 by a small team of people, and later adopted by Mozilla.
It is a compiled low-level language, which aims to be as fast as C or C++, while incorporating some features from high-level languages such as Go, Python, or JavaScript.
Rust has three main goals:
- Performance
- Safety
- Productivity
Performance
Rust aims to achieve performance similar to C or C++.
Rust is statically typed, which means the data type of a variable is known at compile time. This allows the compiler to optimize the code further than if we didn’t know the types.
Rust does not use garbage collection (despite being a low-level programming language). Garbage collection is where the program attempts to reclaim memory from objects no longer in use by the program.
Unlike languages like Python and JavaScript, Rust avoids these abstractions to minimize issues, making it a preferred choice for low-level programming.
Safety
Rust is designed to be completely memory safe. This means that memory-related exploits aren’t possible in Rust, unless you explicitly specify unsafe Rust code.
The Microsoft Security Response Centre reports that 70% of all CVEs assigned are memory safety issues. Microsoft states:
“This means that if that software had been written in Rust, 70% of these security issues would most likely have been eliminated. And we’re not the only company to have reported such findings.”
Rust provides tools to wrap unsafe actions, enabling static enforcement of unsafe code by the Rust compiler.
The memory safety is guaranteed by the concept of ownership, governed by these rules:
- Each value has a variable, called an owner.
- There can only be one owner at a time.
- When the owner goes out of scope, the value will be dropped.
Values can be moved or borrowed between variables, but no value can have more than one owner.
Consider an example in Python:z
squares = (val * val for val in range(100)) print(min(squares)) print(max(squares))
What we want is:
0 9801
But what we get is:
>>> print(min(squares)) 0 >>> print(max(squares)) Traceback (most recent call last): File "", line 1, in ValueError: max() arg is an empty sequence
This is because min alters the variable squares. It’s strange, because we just wanted the minimum — not to alter the whole variable!
In Rust, the same code is:
fn main()
let squares = (0..100).map(|val| val * val);
println!("{:?}", squares.min());
println!("{:?}", squares.max());
}
When we try to compile this, Rust tells us:
error[E0382]: use of moved value: `squares`
--> ownership.rs:4:21
|
3 | println!("{:?}", squares.min());
| ------- value moved here
4 | println!("{:?}", squares.max());
| ^^^^^^^ value used here after move
|
= note: move occurs because `squares` has type `std::iter::Map<std::ops::Range, [closure@ownership.rs:2:31: 2:40]>`, which does not implement the `Copy` trait
The important part here is that Python allows functions to alter variables they do not own, whereas Rust doesn’t.
Productivity
Rust’s third major goal is productivity, and it provides a rich set of tools to support developers.
Note: The below list is read as:
- Tool
Explanation of the above tool.
Some of these tools include:
- Cargo
Rust’s version of NPM or PyPi. Download packages others have created.
- Clippy
Microsoft Clippy, but re-imagined for Rust to aid with development.
- RustFmt
Automatically formats Rust code.
- Cargo Test
A built-in testing application created by the Rust developers.
- Cargo docs
Automatically generates documentation for your code using documentation comments (written in Markdown). This documentation is then sent to docs.rs upon publishing to Cargo. Moreover, examples in documentation are automatically tested for you, eliminating untested documentation examples.
- Rust-Analyzer
Rust Analyzer is like an intelligent IDE. It clearly labels what’s wrong with your code, explains why it’s wrong, points out the exact characters causing errors, and often provides an “auto-fix” function that rectifies errors automatically.
- The Rust Book & Docs
Rust offers a comprehensive book called The Book, which covers everything you need to know about Rust. Neatly divided into chapters, it’s easily searchable and available for free. Additionally, due to Rust’s documentation comments, most libraries you use will have extensive documentation online.
With these tools at your disposal, compiling a Rust program and encountering bugs is incredibly rare. The tooling and language usually catch issues long before you hit the compile button.
Conclusion
If you are seeking exceptional speed, memory safety, and enhanced productivity, Rust is the language you’ve been looking for.
As Pentesters, part of our job is to provide solutions to developers. While suggesting a low-level language like Rust to Python developers might seem unconventional initially, Rust offers robust support, even allowing calls from functions written in other languages through foreign function interfacing.
We can leverage Rust to rewrite security or performance-critical code that seamlessly integrates with our existing codebase.
Here’s an example of calling C code:
extern "C" {
fn abs(input: i32) -> i32;
}
fn main() {
unsafe {
println!("C believes that the absolute value of -3 is: {}", abs(-3));
}
}















