Skip to content

Instantly share code, notes, and snippets.

@maurelian
Last active November 17, 2020 12:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maurelian/5958de28d05db96ef00031a41eb713a8 to your computer and use it in GitHub Desktop.
Save maurelian/5958de28d05db96ef00031a41eb713a8 to your computer and use it in GitHub Desktop.

About rust security and auditing

  • Review clippy warnings; most of the time these are benign or irrelevant, but they can help spotting red flags.
  • Build and run all the unit tests, assess the code coverage and keep note of the un(der)tested component.
  • Review the dependencies listed in Cargo.toml and Cargo.lock: Will the latest version be used? (preferable but not always the right choice) Are these established, trustworthy packages? You may use the subcommand cargo-audit (thanks @dues__ for the pointer).
  • Look for unsafe code blocks, and evaluate the risk (can an attacker control the input used in these blocks? etc.)
  • Look for risky uses of unwrap(), which can cause panics, as opposed to pattern-matched errors.
  • Look for potential integer overflows (these will cause a panic when run in debug mode, but will silently wrap around in release mode).
  • Look for “public-in-private” types, whose behavior may not be as intended and could be used to bypass privacy checks.
  • Look for any recursive function calls and see if they could be abused to overflow the stack.
  • If FFI is used, find the foreign code called, and if relevant add its audit as a subproject.
  • Identify APIs that could benefit from being fuzzed, keep note of these.
  • Find which crypto primitives are used, what third-party libraries if any, and keep note of any new implementations of crypto components.
  • Find what RNG is used for crypto and security purposes? rand::thread_rng should be fine most of the time, but may fall back to a weak RNG is the OS’ fails.
  • Are sensitive values set to zero after being used? In Rust this may be done using the Drop trait rather than explicitly.
  • In Rust, the "unsafe" code is pretty much the "code that defies automatic auditing". If there are properties of unsafe code that can be made verifiable, i.e. safe, then they are generally standardized in some way that allows them to be used in "safe" (verifiable) code.
  • My workflow was roughly like this:
  1. See if the crate has been fuzzed yet to identify low-hanging fruit.
  2. If it has been fuzzed, check sanity of fuzzing harness.
  3. If something is amiss, fuzz the crate.
  4. In case fuzzing turns up no bugs, eyeball the unsafes and try to check them for memory errors.
  5. If no horrific memory errors turn up, try to replace whatever’s under unsafe with safe code without sacrificing performance.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment