Secure Coding Practice in Rust

1dfa2bb34977b1db41d0d46d4505183f?s=47 Osuke
October 26, 2019

Secure Coding Practice in Rust



October 26, 2019


  1. 2.

    • Software Engineer at Layerx Inc., a blockchain startup based

    in Tokyo. • Focusing on development of privacy solutions to blockchain-based systems. ◦ Zero-knowledge proving systems ◦ TEE • Core dev. of Zerochain ◦ Osuke Sudo Twitter: @zoom_zoomzo
  2. 4.

    Memory safety • Without garbage collection to avoid overhead. •

    Without error-prone manual memory allocations and deallocations. • Ownership model ◦ Resources can only have one owner. ◦ let x = vec![1, 2, 3]; : x owns resource vec![1, 2, 3] . ◦ let y = x; : Ownership of resource vec![1, 2, 3] moves to y . ◦ let y = &x; : y borrows ownership of resource vec![1, 2, 3] from x . ◦ Compiler can know variable “lifetime”.
  3. 5.

    Memory safety • Avoiding dangerous memory instructions like… ◦ Data

    races ◦ Dereferencing a null or dangling raw pointer. ◦ Reading undef (uninitialized) memory • Rust programs must never cause undefined behavior.
  4. 6.

    Rust can be “unsafe” • Rust programs can be unsafe

    only if a unsafe keyword is used explicitly. • The code inside unsafe blocks can break memory safety. ◦ Dereference a raw pointer ◦ Mutable global items: static mut
  5. 8.

    What is NOT “unsafe”? Rust provides the memory system and

    the type system to prevent things like... • Memory leak • Deadlock • Integer overflow • … but these are possible!
  6. 9.

    Memory leak is NOT memory safety • mem::forget • Box::leak

    • Rc and Arc cycles • mpsc::{Sender, Receiver} cycles
  7. 10.

    Drop • Used to run some code when a value

    goes out of scope. • The equivalent of a destructor • Used to release memory or external resources (sockets, files, etc.).
  8. 11.

    Memory leak of sensitive data • Compilers optimize for performance,

    and in doing so they love to "optimize away" unnecessary zeroing calls. • Debuggers or remote machines can access leftover values in memory. • Sensitive data must never be accessible. ◦ private key, password, randomness... • Heartbleed bug in OpenSSL ◦ It leads to the leak of memory contents from the server to the client and vice versa.
  9. 12.

    Zeroize • • Zeroize clears sensitive data in memory.

    • Providing the operation that zeroing memory cannot be “optimized away” by the compiler. • The clear_on_drop crate is no longer maintained.
  10. 13.

    Zeroize • #[derive(Zeroize)] : automatically calls zeroize() on all members

    of a struct. • #[zeroize(drop)] : call zeroize() when this item is dropped
  11. 14.

    Zeroize • write_volatile : Performs a volatile write of a

    memory location with the given value and guaranteed to not be elided or reordered by the compiler. • compiler_fence : Restricts the kinds of memory re-ordering the compiler is allowed to do. • Ordering::SeqCst : No re-ordering of reads and writes across this point is allowed.
  12. 15.

    Timing leaks? • Timing leaks could be occured if there

    exists a relationship between the secret data and the execution time of your code. • It’s best practice to write code that is “constant-time” to prevent timing leaks. ◦ More precisely, “Secret-independent resource usage” P A S S W O R D A A S S W O R D P A S S W O R D P A S S W O D D
  13. 16.

    Subtle • • Pure-Rust traits and utilities for constant-time

    cryptographic implementations. ◦ 1. The bitwise operations are constant-time ◦ 2. The operations are not optimized into a branch.
  14. 17.
  15. 18.

    Integer overflow • Integer overflow is considered “safe” in Rust.

    • cargo run detects integer overflow, but cargo run --release doesn’t. • How we can program integer overflow explicitly?
  16. 20.

    Unsecure PRNGs • Use rand crate ◦ Note; Breaking changes

    happend between v0.4 and v0.5 • Use rand::rngs::OsRng for strong Cryptographically secure PRNGs. ◦ A random number generator that retrieves randomness from the operating system.
  17. 21.

    Fuzzing • An automated software testing technique that involves providing

    unexpected or random data as inputs to a program. • In paticular, useful for hash functions, serializers, or parsers.. • Lots of bugs are founded by fuzzing. ◦ ref: • tools ◦ cargo-fuzz ◦ honggfuzz-rs
  18. 22.

    Tools for secure coding • clippy ◦ A collection of

    lints to catch common mistakes and improve your Rust code. • cargo-audit ◦ Audit Cargo.lock files for crates with security vulnerabilities reported to the RustSec Advisory Database. • cargo-crev ◦ A cryptographically verifiable code review system for the cargo (Rust) package manager.