$30 off During Our Annual Pro Sale. View Details »

Secure Coding Practice in Rust

Osuke
October 26, 2019

Secure Coding Practice in Rust

Osuke

October 26, 2019
Tweet

More Decks by Osuke

Other Decks in Programming

Transcript

  1. Secure Coding Practice in Rust
    Osuke

    View Slide

  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
    ○ https://github.com/LayerXcom/zero-chain
    Osuke Sudo
    Twitter: @zoom_zoomzo

    View Slide

  3. Rust is “fast” and “safe”?

    View Slide

  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”.

    View Slide

  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.

    View Slide

  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

    View Slide

  7. Rust can be “unsafe”
    ● All FFI functions are assumed to be “unsafe”.

    View Slide

  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!

    View Slide

  9. Memory leak is NOT memory safety
    ● mem::forget
    ● Box::leak
    ● Rc and Arc cycles
    ● mpsc::{Sender, Receiver} cycles

    View Slide

  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.).

    View Slide

  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.

    View Slide

  12. Zeroize
    ● https://github.com/iqlusioninc/crates/tree/develop/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.

    View Slide

  13. Zeroize
    ● #[derive(Zeroize)] : automatically calls zeroize() on all members of a struct.
    ● #[zeroize(drop)] : call zeroize() when this item is dropped

    View Slide

  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.

    View Slide

  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

    View Slide

  16. Subtle
    ● https://github.com/dalek-cryptography/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.

    View Slide

  17. Subtle

    View Slide

  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?

    View Slide

  19. Integer overflow

    View Slide

  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.

    View Slide

  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: https://github.com/rust-fuzz/trophy-case
    ● tools
    ○ cargo-fuzz
    ○ honggfuzz-rs

    View Slide

  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.

    View Slide

  23. Thank you!

    View Slide