Skip to content

Security: Kirky-X/oxcache

Security

docs/SECURITY.md

Security Policy

This document describes the security measures built into oxcache, the threat models they mitigate, and the process for reporting security vulnerabilities.

Overview

oxcache provides a defense-in-depth security layer for Redis-backed caching. All security functions are gated behind the redis feature and are automatically enforced by the RedisBackend. They can also be called directly from application code for custom validation scenarios.

1. Redis TLS Enforcement

By default, oxcache requires TLS-encrypted Redis connections (rediss:// scheme). Non-TLS connections (redis://) are rejected at backend construction time with a clear error message.

Bypassing for Development

Non-TLS connections are allowed only when the environment variable OXCACHE_ALLOW_INSECURE_REDIS is explicitly set to one of:

  • I_UNDERSTAND_THE_RISKS
  • development-only
# Development only — never use in production
export OXCACHE_ALLOW_INSECURE_REDIS=I_UNDERSTAND_THE_RISKS

Warning: Setting this variable in production exposes Redis traffic (including credentials) to network interception. The application log will record a warning when this bypass is active.

2. Key Validation

Function: oxcache::validate_redis_key(key: &str) -> Result<()>

Validates Redis keys before they are sent to the server, preventing command injection and malformed key attacks.

Rules

Rule Limit Description
Non-empty Empty keys are rejected
Max length 524,288 bytes (512 KB) Keys exceeding MAX_KEY_LENGTH are rejected
Dangerous chars \r, \n, \0 CR/LF/NULL are rejected (prevent CRLF injection)
Control chars All Unicode control chars (except \t) Prevents binary/escape sequence injection

Example

use oxcache::validate_redis_key;

validate_redis_key("user:123")?;           // OK
validate_redis_key("user\r\nSET foo bar")?; // Err — CRLF injection detected
validate_redis_key("")?;                    // Err — empty key

3. Lua Script Sandbox

Function: oxcache::validate_lua_script(script: &str, key_count: usize) -> Result<()>

Validates Lua scripts before EVAL/EVALSHA execution, preventing server-side resource exhaustion and dangerous command execution.

Rules

Rule Limit Description
Max script length 10,240 bytes (10 KB) MAX_LUA_SCRIPT_LENGTH — prevents memory exhaustion
Max key count 100 keys MAX_LUA_SCRIPT_KEYS — prevents argument flooding
Forbidden commands FLUSHALL, FLUSHDB, SHUTDOWN, CONFIG, KEYS *, infinite loop patterns Blocks destructive and resource-draining operations

The validator preprocesses the script to strip comments, string literals, and long-bracket content before pattern matching, preventing evasion via string obfuscation.

Example

use oxcache::validate_lua_script;

// Safe script
validate_lua_script("return redis.call('GET', KEYS[1])", 1)?;

// Rejected — FLUSHALL is forbidden
validate_lua_script("redis.call('FLUSHALL')", 0)?;

// Rejected — too many keys
validate_lua_script("return 1", 101)?;

4. SCAN Pattern Restrictions

Function: oxcache::validate_scan_pattern(pattern: &str) -> Result<()> Function: oxcache::clamp_scan_count(count: usize) -> usize

Validates SCAN patterns and clamps COUNT to prevent Redis server overload.

Rules

Rule Limit Description
Max pattern length 256 chars MAX_SCAN_PATTERN_LENGTH — prevents regex DoS
Max wildcards 10 MAX_SCAN_WILDCARDS — prevents broad scans
Clamped COUNT 10,000 clamp_scan_count caps COUNT to prevent full-keyspace scans

Example

use oxcache::{validate_scan_pattern, clamp_scan_count};

validate_scan_pattern("user:*")?;              // OK
validate_scan_pattern("*:*:*:*:*:*:*:*:*:*:*")?; // Err — too many wildcards

let count = clamp_scan_count(1_000_000);       // Returns 10_000

5. Connection String Redaction

Function: RedisBackend::redact_connection_string(conn_str: &str) -> String Function: oxcache::redact_value(value: &str, visible_chars: usize) -> String Function: oxcache::redact_cache_key(key: &str) -> String Function: oxcache::redact_field(field_name: &str, value: &str) -> String

These functions ensure credentials and sensitive data never appear in logs or error messages.

Example

use oxcache::backend::memory::redis::RedisBackend;

let conn_str = "redis://:secret_password@localhost:6379/0";
let redacted = RedisBackend::redact_connection_string(conn_str);
// redacted == "redis://[REDACTED]@localhost:6379/0"
assert!(!redacted.contains("secret_password"));

6. Logging Security

Function: oxcache::log_cache_key(key: &str) -> String Function: oxcache::sanitize_message(msg: &str) -> String

These utilities ensure cache keys and log messages are sanitized before being written to logs, preventing log injection attacks.

Threat Model

Threat Mitigation
CRLF injection via Redis keys validate_redis_key rejects \r, \n, \0
Command injection via Lua scripts validate_lua_script blocks FLUSHALL, CONFIG, etc.
Redis server overload via SCAN validate_scan_pattern + clamp_scan_count
Credential leakage in logs redact_connection_string, redact_value
Man-in-the-middle on Redis traffic TLS enforcement (rediss:// by default)
Resource exhaustion via large Lua scripts MAX_LUA_SCRIPT_LENGTH (10 KB) and MAX_LUA_SCRIPT_KEYS (100)
Log injection via cache keys sanitize_message, log_cache_key

Security Reporting Process

Reporting a Vulnerability

If you discover a security vulnerability in oxcache:

  1. Do NOT open a public GitHub issue.
  2. Email the maintainer at the address listed in the Cargo.toml authors field.
  3. Include:
    • A description of the vulnerability
    • Steps to reproduce (proof of concept)
    • Affected versions
    • Suggested fix (if any)
  4. You will receive an acknowledgment within 48 hours.
  5. A fix will be developed and released following responsible disclosure timelines.

Supported Versions

Only the latest minor release receives security updates. When a new minor version is released, the previous minor version receives critical fixes for 30 days only.

Configuration Summary

Setting Default Override
Redis TLS Required (rediss://) OXCACHE_ALLOW_INSECURE_REDIS=I_UNDERSTAND_THE_RISKS
Max key length 512 KB Hardcoded (MAX_KEY_LENGTH)
Max Lua script length 10 KB Hardcoded (MAX_LUA_SCRIPT_LENGTH)
Max Lua script keys 100 Hardcoded (MAX_LUA_SCRIPT_KEYS)
Max SCAN pattern length 256 chars Hardcoded (MAX_SCAN_PATTERN_LENGTH)
Max SCAN wildcards 10 Hardcoded (MAX_SCAN_WILDCARDS)
Clamped SCAN COUNT 10,000 clamp_scan_count()

There aren't any published security advisories