Skip to content

Security: cryptidtech/multi-base

Security

SECURITY.md

Security Policy

Security Review

This document describes the security posture of the multi-base crate. It gives guidance for users on security considerations.

Security Review Results

No Critical Vulnerabilities Found

The codebase was reviewed for common security issues. No critical vulnerabilities were found.

Areas Reviewed

  1. Integer Overflow. Safe.

    • All size calculations use checked arithmetic in debug mode.
    • Capacity calculations for String and Vec use addition. The allocation fails before overflow.
    • Risk: Low. An attack would need near-usize::MAX inputs. Memory allocation fails first.
  2. Buffer Overflow and Underflow. Safe.

    • All string slicing uses char::len_utf8() for UTF-8 boundary detection.
    • No unsafe code or manual pointer arithmetic.
    • Rust bounds checking prevents buffer overflows.
    • Risk: None. Protected by Rust safety guarantees.
  3. Panic Conditions. Safe.

    • Identity encoding uses String::from_utf8_lossy. No panic on invalid UTF-8.
    • All decode operations return Result.
    • Empty inputs return Error::EmptyInput.
    • Invalid base codes return Error::UnknownBase.
    • One .expect() in encode_to_validated(). It cannot fail in practice.
    • Risk: Minimal. Library functions do not panic on arbitrary input.
  4. Resource Exhaustion Attacks. Consider.

    • No hard limits on input size.
    • Large inputs consume proportional memory.
    • Memory allocation failures are handled by the Rust allocator.
    • Risk: Medium. Applications should set their own size limits.
    • Recommendation: Applications that process untrusted input should enforce a maximum size limit.
  5. Input Validation. Complete.

    • Empty strings return Error::EmptyInput.
    • Invalid base codes return Error::UnknownBase.
    • Malformed encoded data is rejected by base-specific decoders.
    • All validation goes through Result types.
    • Risk: None. Input validation at all boundaries.

Security Best Practices for Users

1. Input Size Limits

For applications that process untrusted input, set a maximum size limit:

const MAX_INPUT_SIZE: usize = 10 * 1024 * 1024; // 10 MB

fn safe_decode(input: &str) -> Result<(Base, Vec<u8>), Error> {
    if input.len() > MAX_INPUT_SIZE {
        return Err(Error::InvalidBaseString);
    }
    multi_base::decode(input, true)
}

2. Error Handling

Handle errors. Do not expose detailed error messages to untrusted parties:

match multi_base::decode(untrusted_input, true) {
    Ok((base, data)) => {
        // Process data
    }
    Err(_) => {
        // Log the error internally. Return a generic error to the user.
        eprintln!("Invalid multibase input");
    }
}

3. Identity Encoding

The Identity encoding (\0 prefix) uses lossy UTF-8 conversion:

  • Invalid UTF-8 bytes are replaced with the Unicode replacement character (U+FFFD).
  • This prevents panics. Invalid UTF-8 does not round-trip.
  • For binary data that must round-trip, use a different base encoding.
// For binary data preservation, use Base64 or Base58
let encoded = multi_base::encode(Base::Base64, binary_data);

// Identity is for UTF-8 text only
let text_encoded = multi_base::encode(Base::Identity, "valid utf-8 text".as_bytes());

4. Strict vs Permissive Decoding

Use strict decoding for untrusted input:

// For untrusted input, use strict mode
let (base, data) = multi_base::decode(untrusted, true)?;

// Permissive mode allows case-insensitive decoding for some bases
let (base, data) = multi_base::decode(trusted, false)?;

Security Testing

The crate has 17 security tests in tests/security.rs. They cover:

  • Large input handling (up to 1 MB).
  • Malformed and malicious input patterns.
  • Buffer reuse safety.
  • Concurrent operation safety.
  • Resource exhaustion resistance.
  • Integer overflow safety.
  • Invalid UTF-8 handling.
  • Empty and truncated input handling.

Run security tests:

cargo test --test security

Fuzzing

The crate can be fuzzed with cargo-fuzz. Fuzz targets:

  1. fuzz_decode — Decode arbitrary strings. Checks for panics on any input.
  2. fuzz_encode — Encode arbitrary bytes. Checks for panics on any binary data.
  3. fuzz_roundtrip — Encode and decode round-trip. Checks encode and decode consistency.

Set Up Fuzzing

# Install cargo-fuzz
cargo install cargo-fuzz

# Run fuzz tests
cargo fuzz run fuzz_decode
cargo fuzz run fuzz_encode
cargo fuzz run fuzz_roundtrip

Dependency Security

The crate depends on:

  • base-x (0.2.7) — Variable-radix base encoding.
  • data-encoding (2.3.1) — Standard base encodings.
  • thiserror (2.0) — Error handling.

The Base256Emoji codec is implemented inline. The external base256emoji dependency was dropped. See CHANGELOG.md.

All dependencies are maintained and used in the Rust ecosystem.

Reporting Security Issues

If you find a security vulnerability in the multi-base crate, report it as follows:

  1. Do not open a public GitHub issue.
  2. Contact the maintainers by email. See Cargo.toml for the address.
  3. Give detailed information about the vulnerability.
  4. Allow reasonable time for a fix before public disclosure.

Security Guarantees

What the Crate Guarantees

  • No panics on arbitrary untrusted input.
  • Memory safety. No unsafe code is used.
  • Input validation at all boundaries.
  • Thread-safe operations. All types are Send + Sync.
  • Error information without exposure of internal state.

What the Crate Does Not Guarantee

  • Protection against resource exhaustion. This is an application responsibility.
  • Constant-time operations. The crate is not for cryptographic use.
  • Perfect round-trip of invalid UTF-8 in Identity encoding.

Changelog of Security-Related Changes

Version 1.0.3

  • Updated SECURITY.md code examples to use multi_base:: instead of the old multibase:: module path.
  • Corrected the stale base256emoji dependency reference.

Version 1.0.2

  • Added #![deny(unsafe_code)] at the crate root.
  • Added clippy lint configuration with unsafe_code = "deny".
  • Added cargo audit job in CI.

Version 1.0.1

  • Fixed Identity encoding panic risk. Now uses lossy UTF-8 conversion.
  • Migrated to thiserror for error handling.
  • Added 17 security tests.
  • Added this SECURITY.md document.

Version 1.0.0

  • Initial release with basic security considerations.

There aren't any published security advisories