Skip to content

Conversation

@dugshub
Copy link
Contributor

@dugshub dugshub commented Oct 1, 2025

Summary

This PR implements a complete, production-ready type system for CLI Patterns with comprehensive security hardening. It addresses issues CLI-4, CLI-5, and CLI-6, providing the foundation for the wizard engine.

Changes Overview

🎯 Core Type System (CLI-4)

  • Semantic types for type safety: BranchId, ActionId, OptionKey, MenuId, StateValue
  • Factory functions with optional validation and global config support
  • Type guards for runtime type checking
  • MyPy strict mode compliance throughout

📋 Pydantic Models (CLI-5)

  • Wizard configuration models with discriminated unions
  • Action types: BashActionConfig, PythonActionConfig
  • Option types: StringOptionConfig, SelectOptionConfig, PathOptionConfig, NumberOptionConfig, BooleanOptionConfig
  • Navigation: MenuConfig, BranchConfig, WizardConfig
  • State management: SessionState
  • Result types: ActionResult, CollectionResult, NavigationResult

🔒 Security Hardening (CLI-6)

This PR includes three security enhancement commits:

1. Command Injection Prevention (CRITICAL) ✅

Commit: feat(security): add command injection prevention to SubprocessExecutor

  • SubprocessExecutor now uses create_subprocess_exec() by default (safe mode)
  • Added allow_shell_features parameter for explicit opt-in to shell features
  • Commands are parsed with shlex and executed without shell interpretation
  • Security warnings logged when shell features are enabled
  • 28 security tests: 15 command injection + 13 integration tests

Breaking Change: Commands now execute without shell by default. Shell features require explicit allow_shell_features=True.

2. Collection Size Limit Tests (MEDIUM) ✅

Commit: test(core): add collection size limit tests for DoS protection

  • BranchConfig limits: 100 actions, 50 options, 20 menus
  • WizardConfig limit: 100 branches
  • SessionState limits: 1000 options, 1000 variables
  • 12 collection limit tests verify existing validators

3. Production Validation Mode (LOW) ✅

Commit: feat(core): add production validation mode with security config

  • New config.py module with SecurityConfig and environment variable support
  • Updated factory functions to respect global validation config
  • Flexible validation: Optional[bool] parameter (None = use config, True/False = override)

Environment Variables

# Enable strict validation (recommended for production)
export CLI_PATTERNS_ENABLE_VALIDATION=true

# Adjust DoS protection limits (defaults shown)
export CLI_PATTERNS_MAX_JSON_DEPTH=50
export CLI_PATTERNS_MAX_COLLECTION_SIZE=1000

# DANGEROUS: Allow shell features globally (not recommended)
export CLI_PATTERNS_ALLOW_SHELL=false

Test Coverage

  • 782 tests passing (100% success rate)
  • MyPy strict mode: No type errors across 38 source files
  • Code formatting: All files formatted correctly

Test breakdown:

  • 191 core unit tests
  • 15 command injection tests
  • 27 validator tests
  • 12 collection limit tests
  • 13 subprocess security integration tests

Security Posture

  • ✅ Command injection completely prevented by default
  • ✅ DoS attack surface significantly reduced
  • ✅ All input validation in place
  • Secure defaults (shell features disabled)
  • Clear opt-in model for dangerous features
  • Comprehensive logging for security events

Breaking Changes

⚠️ SubprocessExecutor behavior change:

Commands now execute without shell by default (security hardening). Shell features require explicit opt-in.

Migration:

# Before (implicit shell features - VULNERABLE)
await executor.run("echo test | grep foo")

# After (explicit opt-in for shell features)
await executor.run("echo test | grep foo", allow_shell_features=True)

# Or use safe execution (recommended)
await executor.run(["grep", "foo"], stdin=...)

Files Added

  • src/cli_patterns/core/types.py - Semantic types and factory functions
  • src/cli_patterns/core/models.py - Pydantic models with validation
  • src/cli_patterns/core/protocols.py - Runtime-checkable protocols
  • src/cli_patterns/core/validators.py - DoS protection validators
  • src/cli_patterns/core/config.py - Security configuration
  • tests/unit/core/test_command_injection.py - Command injection tests
  • tests/integration/test_subprocess_security.py - Security integration tests

Files Modified

  • src/cli_patterns/execution/subprocess_executor.py - Command injection prevention
  • tests/unit/execution/test_subprocess_executor.py - Updated for security changes
  • tests/unit/core/test_models.py - Added collection limit tests
  • src/cli_patterns/core/__init__.py - Export complete type system

Related Issues

Closes #CLI-4
Closes #CLI-5
Closes #CLI-6

Documentation

See existing commit history for detailed implementation of:

  • DoS protection validators (commit 7319aba)
  • Security hardening to models (commit 2463e4a)
  • Runtime-checkable protocols (commit a0b4790)
  • Pydantic model configuration (commit bc2e490)
  • Semantic type system (commit 95c5541)

🤖 Generated with Claude Code

dugshub and others added 9 commits September 30, 2025 17:53
Implement core semantic types (BranchId, ActionId, OptionKey, MenuId)
with factory functions, type guards, and StateValue for JSON-serializable data.

- NewType definitions for type safety without runtime overhead
- Factory functions with optional validation (default: no overhead)
- Type guards for runtime type checking
- Collection type aliases (BranchList, ActionSet, etc.)
- StateValue type alias for JSON-serializable values
- 100% test coverage with 28 comprehensive tests
- MyPy strict mode compliance

Part of CLI-4: Minimal Core Type Definitions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implement comprehensive Pydantic v2 models for wizard system including
actions, options, branches, and complete wizard configuration.

Models:
- BaseConfig: Common fields (metadata, tags) for all configs
- Action types: BashActionConfig, PythonActionConfig (discriminated unions)
- Option types: String, Select, Path, Number, Boolean (discriminated unions)
- MenuConfig: Navigation menu configuration
- BranchConfig: Complete branch with actions, options, menus
- WizardConfig: Top-level wizard configuration
- SessionState: Unified wizard + parser state
- Result types: ActionResult, CollectionResult, NavigationResult

Features:
- Discriminated unions for type-safe extensibility
- Pydantic v2 with ConfigDict
- Strict validation enabled
- Field descriptions for all attributes
- 100% test coverage with 42 comprehensive tests
- MyPy strict mode compliance

Part of CLI-4: Minimal Core Type Definitions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implement core protocols defining interfaces for action execution,
option collection, and navigation control.

Protocols:
- ActionExecutor: Execute actions (bash, python, etc.)
- OptionCollector: Collect option values from users
- NavigationController: Handle wizard navigation

Features:
- All protocols are @runtime_checkable for isinstance() checks
- Enables dependency injection and multiple implementations
- Type-safe interfaces with Protocol typing
- Comprehensive documentation with usage examples
- 100% test coverage with 15 tests including integration patterns
- MyPy strict mode compliance

Part of CLI-4: Minimal Core Type Definitions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive exports for all types, models, and protocols from
the core module, making them easily accessible to other parts of
the framework.

Exports:
- Semantic types and factory functions
- All configuration models (actions, options, branches, wizard)
- All protocols (ActionExecutor, OptionCollector, NavigationController)
- Result types
- Type guards and collection aliases

Part of CLI-4: Minimal Core Type Definitions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implement validation functions to prevent DoS attacks via deeply nested
or excessively large data structures in StateValue fields.

Validators:
- validate_json_depth(): Prevent stack overflow (max 50 levels)
- validate_collection_size(): Prevent memory exhaustion (max 1000 items)
- validate_state_value(): Combined validation for StateValue

Features:
- Recursive depth checking with early termination
- Total element counting in nested structures
- Clear error messages with limits
- Configurable limits via parameters
- 27 comprehensive tests covering edge cases

Security Benefits:
- Prevents stack overflow during JSON serialization
- Prevents memory exhaustion from large collections
- Prevents CPU exhaustion during parsing
- 100% test coverage

Part of security hardening (Priority 2: DoS Protection)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implement multiple layers of security protection in core models to prevent
command injection, DoS attacks, and resource exhaustion.

Security Enhancements:

1. Command Injection Prevention (BashActionConfig):
   - Added allow_shell_features flag (default: False)
   - Validates commands to block shell metacharacters
   - Rejects: pipes, redirects, command substitution, variable expansion
   - Clear error messages guide users to explicit opt-in
   - 13 tests for injection patterns

2. DoS Protection (SessionState):
   - Validates option_values and variables for depth/size
   - Maximum 1000 options/variables
   - Integration with validators module
   - 8 tests for DoS scenarios

3. Collection Size Limits:
   - BranchConfig: 100 actions, 50 options, 20 menus
   - WizardConfig: 100 branches
   - Prevents memory exhaustion from config files
   - 6 tests for collection limits

4. Entry Branch Validation (WizardConfig):
   - Ensures entry_branch exists in branches list
   - Helpful error messages show available branches
   - 3 tests for validation scenarios

Test Coverage:
- 30 security-focused tests in test_security.py
- All existing tests updated and passing
- 100% coverage of new security code

Breaking Changes:
- Commands with shell features now require allow_shell_features=True
- Wizard configs with invalid entry_branch now fail validation
- Large collections/deep nesting now rejected

Migration:
- Set allow_shell_features=True for commands needing pipes/redirects
- Ensure entry_branch matches a branch ID
- Review any configs with >100 branches or >50 options

Part of security hardening (Priorities 1, 2, 3)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implements Priority 1 (CRITICAL) security enhancement: command injection prevention.

Changes:
- Modified SubprocessExecutor to use create_subprocess_exec() by default (safe mode)
- Added allow_shell_features parameter for explicit opt-in to shell features
- Commands are parsed with shlex and executed without shell interpretation by default
- Added security warning logging when shell features are enabled
- Invalid shell syntax is caught and reported gracefully

Security Impact:
- Command injection attacks are now completely prevented by default
- Shell metacharacters (pipes, redirects, command substitution) are treated as literal
- Only explicitly trusted commands with allow_shell_features=True use shell

Breaking Change:
- Commands now execute without shell by default
- Shell features require explicit allow_shell_features=True parameter

Tests Added:
- 15 command injection unit tests
- 13 security integration tests
- Updated 8 existing subprocess executor tests

All 782 tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implements Priority 3 (MEDIUM) security testing: collection size limits.

Tests Added:
- Branch actions limit: max 100 actions
- Branch options limit: max 50 options
- Branch menus limit: max 20 menus
- Wizard branches limit: max 100 branches
- SessionState option_values limit: max 1000 items
- SessionState variables limit: max 1000 items

Coverage:
- 12 new collection limit tests
- Tests both boundary conditions (at limit) and violations (over limit)

These tests verify the collection size validators already implemented
in models.py prevent DoS attacks via memory exhaustion.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implements Priority 4 (LOW) security enhancement: production validation mode.

Changes:
- New config.py module with SecurityConfig TypedDict
- Environment variable support for security settings
- Updated factory functions to respect global validation config
- Factory functions now accept Optional[bool] for validation:
  - None: use global config (default)
  - True: force validation
  - False: skip validation

Environment Variables:
- CLI_PATTERNS_ENABLE_VALIDATION: Enable strict validation (default: false)
- CLI_PATTERNS_MAX_JSON_DEPTH: Max nesting depth (default: 50)
- CLI_PATTERNS_MAX_COLLECTION_SIZE: Max collection size (default: 1000)
- CLI_PATTERNS_ALLOW_SHELL: Allow shell features globally (default: false)

Benefits:
- Zero-overhead validation in development (default: off)
- Easy enablement for production via environment variable
- Consistent validation behavior across all factory functions
- Configurable DoS protection limits

Usage:
```bash
# Production deployment
export CLI_PATTERNS_ENABLE_VALIDATION=true
```

All 782 tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@dugshub dugshub closed this Oct 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants