Crate safename

Crate safename 

Source
Expand description

Filename and path validation for security hardening.

This library provides validation and sanitization rules inspired by David A. Wheeler’s proposed Linux safename LSM. The goal is to harden systems against attacks that exploit unusual filenames to trick shell scripts, command-line tools, and applications with imperfect input handling.

§API Overview

The library provides two sets of functions:

Note: This library does not perform path canonicalization, symlink resolution, or .. traversal handling. These operations have their own security implications (TOCTOU races, symlink attacks) and should be handled separately by the caller.

§Default Rules

The default validation blocks:

  • Control characters (0x00-0x1F, 0x7F) - prevents terminal escape sequence attacks
  • Leading dash (-) - prevents interpretation as command-line options
  • Leading tilde (~) - prevents shell home directory expansion
  • Leading and trailing spaces - prevents quoting bugs and argument splitting
  • Byte 0xFF - invalid UTF-8 leading byte

§Feature Flags

Features are organized into tiers:

  • low (default): Cross-platform safety

    • block-colon: Blocks : (PATH injection)
    • block-backslash: Blocks \ (path traversal via normalization)
  • require-utf8 (default): Requires valid UTF-8 encoding

  • medium: Shell safety (includes low)

    • block-quotes: Blocks " and '
    • block-chaining: Blocks &, ;, | (for &&, ;, ||)
    • block-redirection: Blocks |, >, <
    • block-expansion: Blocks $, %, *, ?, `
  • high: Maximum restriction (includes medium)

    • block-brackets: Blocks (, ), [, ]
    • block-space: Blocks spaces everywhere (not just leading/trailing)
  • require-ascii: ASCII-only (bytes 0x00-0x7F), mutually exclusive with require-utf8

Note: require-utf8 and require-ascii cannot be enabled together (compile-time error).

§Example

use safename::{is_file_safe, is_path_safe, validate_file};

// Filename validation (single component, no slashes)
assert!(is_file_safe("normal_file.txt"));
assert!(!is_file_safe("-rf"));  // Leading dash
assert!(!is_file_safe("file\x00name"));  // Contains NUL

// Path validation (full or partial paths)
assert!(is_path_safe("/home/user/file.txt"));
assert!(!is_path_safe("/home/-rf"));  // Component starts with dash

// Get detailed error information
let result = validate_file(b"~/.bashrc");
assert!(result.is_err());

Structs§

FileSanitizationOptions
Configuration for filename sanitization.
FileValidationOptions
Configuration for filename validation.
PathError
Error type for path validation, including the component index.
PathSanitizationOptions
Configuration for path sanitization.
PathValidationOptions
Configuration for path validation.

Enums§

SafeNameError
Error type describing why a filename is unsafe.

Constants§

DEFAULT_MAX_FILE_LEN
Default maximum filename length (NAME_MAX on most Unix systems).
DEFAULT_MAX_PATH_LEN
Default maximum path length (PATH_MAX on most Unix systems).
REPLACEMENT_CHAR
Unicode replacement character (U+FFFD) encoded as UTF-8.
REPLACEMENT_UNDERSCORE
ASCII underscore as a single-byte replacement option.

Functions§

is_file_safe
Checks if a filename is safe according to all enabled validation rules.
is_path_safe
Checks if a full path is safe according to all enabled validation rules.
sanitize_file
Sanitizes a filename by replacing invalid bytes with underscore.
sanitize_file_with_options
Sanitizes a filename with custom options.
sanitize_path
Sanitizes a full path by sanitizing each component.
sanitize_path_with_options
Sanitizes a full path with custom options.
validate_file
Validates a filename component (what you’d get from Path::file_name()).
validate_file_with_options
Validates a filename component with custom options.
validate_path
Validates a full path by splitting on / and validating each component.
validate_path_with_options
Validates a full path with custom options.

Type Aliases§

PathResult
Result type alias for path validation.
SafeNameResult
Result type alias using SafeNameError.