Expand description
Convenience macros for creating errors with format strings.
§Security Model
These macros enforce compile-time safety to prevent untrusted data from leaking into error messages without explicit sanitization.
§Rules
- Operation names MUST be string literals - prevents dynamic injection
- Format strings MUST be string literals - prevents format string attacks
- Format arguments must be sanitized via
sanitized!()wrapper - bounded length
§Usage
let line_num = 42;
// ✓ CORRECT: Format string is literal, variable is sanitized
let err = config_err!(
&definitions::CFG_PARSE_FAILED,
"validate",
"Invalid value at line {}",
sanitized!(line_num)
);ⓘ
let user_input = "attacker data";
// ✗ COMPILE ERROR: Operation must be a literal
let err = config_err!(&definitions::CFG_PARSE_FAILED, user_input, "Failed");ⓘ
let unsanitized = "oops";
// ✗ COMPILE ERROR: Args must be wrapped in sanitized!()
let err = config_err!(&definitions::CFG_PARSE_FAILED, "op", "{}", unsanitized);§Sanitization
The sanitized!() macro truncates strings to prevent DoS via massive error messages
and ensures all format arguments are bounded in length.
§Security Properties
This module implements several security principles to make the error macro system dumb-proof and secure:
- Compile-time Literal Enforcement: Requires operation names, details, and format strings to be string literals, preventing runtime injection or format string vulnerabilities.
- Mandatory Sanitization for Dynamic Data: Dynamic arguments must be explicitly wrapped in
sanitized!()macro. This prevents accidental inclusion of unsanitized data. - Length Bounding and Truncation: Sanitized values are strictly limited to 256 characters to prevent DoS through oversized error messages or logs.
- UTF-8 Boundary Respect: Truncation always occurs at valid character boundaries to avoid creating invalid strings that could cause downstream parsing errors.
- Control Character Neutralization: Non-printable control characters are replaced with ‘?’ to prevent log injection, formatting disruption, or terminal escape sequence attacks.
- Sensitive Data Isolation: Sensitive information (e.g., passwords, keys) must use dedicated
_sensitivemacros and is isolated to internal logs only—never exposed in external error messages. - No External Sensitive Logging: Sensitive data is structurally separated and cannot be accidentally included in public-facing error details by convention.
- Pure Macro Expansion: Macros expand to pure expressions without side effects, I/O, or runtime dependencies beyond standard library.
- Defense in Depth: Multiple layers including literal requirements, sanitization, and separation ensure even if one layer fails, others protect.
- Fail-Safe Defaults: Invalid UTF-8 or truncation failures default to safe placeholders like “[INVALID_UTF8]” instead of panicking or leaking.
- No Side Channels: Sanitization is deterministic and linear-time relative to input length (up to bound), avoiding attacker-controlled amplification.
- Dumb-Proof Design: By requiring explicit
sanitized!()for args and literals for formats, accidental misuse (e.g., logging raw sensitive data externally) fails at compile time or produces safe output.
Note: While format! allocates, this is acceptable for error paths. For hot paths, consider pre-formatted strings.
Constants§
- MAX_
SANITIZED_ LEN - Maximum length for sanitized strings in error messages.