Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Security

towl applies defence-in-depth across configuration, scanning, and output.

Path Traversal Protection

All user-supplied paths are checked for .. components before use:

  • Config paths -- towl init --path rejects traversal attempts
  • Scan paths -- towl scan <path> validates before walking
  • Output paths -- -o <path> is validated and symlinks are resolved

The check uses contains_path_traversal() which inspects each path component for ...

Output file paths are resolved via std::fs::canonicalize() before writing. This prevents symlink-based escape from the intended output directory.

Resource Limits

Hard limits prevent denial-of-service via large repositories or malicious inputs:

LimitValuePurpose
Max file size10 MBPrevents reading huge binary/generated files
Max TODOs per file10,000Bounds per-file memory usage
Max total TODOs100,000Bounds overall memory usage
Max files scanned100,000Bounds directory walk
Max pattern length256 charsPrevents regex DoS via long patterns
Max compiled regex256 KBBounds regex engine memory
Max total patterns (combined)50Bounds total regex compilation across all categories
Max patterns per config field100Limits config file attack surface

Secret Handling

The GitHub token (TOWL_GITHUB_TOKEN) is:

  • Never stored in config files -- Only accepted via environment variable
  • Stored as SecretString -- Uses the secrecy crate
  • Masked in debug output -- Debug and Display show [REDACTED]
  • Zeroed on drop -- Memory is cleared when the config is dropped

Environment Variable Restriction

Only three environment variables are read:

VariablePurpose
TOWL_GITHUB_TOKENGitHub authentication
TOWL_GITHUB_OWNERRepository owner override
TOWL_GITHUB_REPORepository name override

No other environment variables influence behaviour.

Config File Safety

  • --force required for overwriting existing config files
  • Pattern array limits -- Each pattern field is capped at 100 entries
  • Pattern length limits -- Individual regex patterns capped at 256 characters
  • TOML parsing -- Uses config crate with serde for type-safe deserialization

Git Integration

  • Git operations use tokio::process::Command to run git as a subprocess
  • Only read-only git commands are executed (git remote get-url origin)
  • No git credentials are accessed or stored

.gitignore Respect

The ignore crate automatically respects .gitignore rules during directory walking, preventing scanning of files the user has excluded from version control.

Error Messages

Error messages include file paths and context for debugging but do not expose internal implementation details or sensitive data. The SecretString type ensures tokens cannot leak through error formatting.

Threat Model

ThreatMitigation
Path traversal via config/scan/output paths.. component detection, symlink resolution
Regex DoS via malicious patternsPattern length limit (256), regex size limit (256 KB), total pattern cap (50)
Memory exhaustion via large reposFile size, TODO count, and file count limits
Token leakageSecretString, env-only token, masked debug
Config file overwrite--force flag required
Arbitrary file write via symlinkscanonicalize() on output paths
Scanning outside intended directory.gitignore respect, extension filtering