multi-base 1.0.4

multibase in rust
Documentation
# 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:

```rust
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:

```rust
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.

```rust
// 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:

```rust
// 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:

```bash
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

```bash
# 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.