Security Best Practices for Deploying the Claude Code Telegram Bot: A Complete Guide to DISABLE_SECURITY_PATTERNS and Safe Configuration
Never set DISABLE_SECURITY_PATTERNS=true in production deployments; always configure a restricted APPROVED_DIRECTORY, enable user authentication, and activate rate limiting to prevent command injection and path traversal attacks.
The Claude Code Telegram bot (RichardAtCT/claude-code-telegram) implements a multi-layer defense model centered in src/security/validators.py to isolate the host system from malicious input. Properly configuring the security validators, authentication providers, and environment variables—particularly the DISABLE_SECURITY_PATTERNS flag—is critical when exposing this bot to Telegram users.
Core Security Architecture in validators.py
The SecurityValidator class in src/security/validators.py serves as the primary gatekeeper for all user-supplied paths, filenames, and command arguments. Upon initialization, it resolves the APPROVED_DIRECTORY and maintains strict boundaries via the _is_within_directory helper method. Every file operation first validates that the resolved path remains within this jail, preventing directory traversal attacks that attempt to escape via .. sequences or symbolic links.
The validator also maintains a comprehensive list of DANGEROUS_PATTERNS (regular expressions) that catch shell metacharacters including $(), ;, &&, |, and >. When disable_security_patterns is left as false (the default), the validate_path method (lines 61–75) checks all input against these patterns before allowing filesystem access.
Configuring the APPROVED_DIRECTORY Jail
The APPROVED_DIRECTORY setting defines a dedicated, write-protected folder that the bot is permitted to touch. All path resolution is relative to this directory.
- Set the
APPROVED_DIRECTORYenvironment variable to a specific folder (e.g.,/var/bot-sandboxor/home/user/bot-files). - Ensure the directory has restricted permissions (read/write only for the bot process, no execute permissions on uploaded files).
- The validator rejects any request that escapes this boundary via the
_is_within_directorycheck insrc/security/validators.py(lines 34–40).
from pathlib import Path
from src.security.validators import SecurityValidator
from src.config.settings import Settings
settings = Settings()
validator = SecurityValidator(
approved_directory=Path(settings.APPROVED_DIRECTORY),
disable_security_patterns=False # Always false in production
)
# Validating user-supplied paths before file operations
is_ok, resolved_path, error = validator.validate_path(user_input)
if not is_ok:
raise PermissionError(error)
# Safe to proceed with resolved_path
Understanding the DISABLE_SECURITY_PATTERNS Flag
The DISABLE_SECURITY_PATTERNS configuration option (defined in src/config/settings.py) controls whether the bot skips regex-based validation of dangerous characters. Keeping this flag false is essential for production security, as it prevents command injection and path traversal by validating every input against the DANGEROUS_PATTERNS list.
When Security Patterns Are Required
With patterns enabled (the default), the validate_path and sanitize_command_input methods in src/security/validators.py actively block:
- Path traversal sequences (
..) - Command substitution (
$()) - Shell operators (
;,&&,|,>,<) - Control characters and null bytes
Dangerous: Disabling Patterns in Production
Setting DISABLE_SECURITY_PATTERNS=true removes the first line of defense. Only enable this in trusted, isolated environments such as sandboxed CI runners where you fully control all inputs and the container has no access to host files outside APPROVED_DIRECTORY. Even in these scenarios, an attacker gaining any foothold could exploit relaxed checks to execute arbitrary shell code.
# WARNING: Only use this configuration in isolated development containers
validator = SecurityValidator(
approved_directory=Path("/tmp/bot-sandbox"),
disable_security_patterns=True # Dangerous - never in production
)
File Upload and Filename Validation
The bot restricts file uploads through a whitelist approach defined in src/security/validators.py. The ALLOWED_EXTENSIONS set defines permissible file types, while FORBIDDEN_FILENAMES blocks dangerous names like .env, .ssh, or executable binaries.
The validate_filename method (lines 66–70) also protects against hidden file attacks by disallowing filenames starting with . unless explicitly permitted (e.g., .gitignore, .gitkeep). Always review the ALLOWED_EXTENSIONS list before deployment and avoid adding executable extensions (.sh, .exe, .bat) unless you have a strict post-upload validation pipeline.
# Validating a Telegram file upload
ok, error = validator.validate_filename(uploaded_filename)
if not ok:
raise ValueError(f"Upload rejected: {error}")
# File extension is allowed and filename is safe
Command Injection Prevention
Before feeding any user string to a subprocess or the Claude tool monitor, pass it through SecurityValidator.sanitize_command_input() (lines 78–95). This method:
- Strips dangerous characters: backticks,
$,;,|,&,<,>,#, and control characters - Enforces a maximum length of 1,000 bytes
- Returns a sanitized string safe for shell execution
Never construct shell commands by concatenating raw user input. Always use the sanitizer:
safe_input = validator.sanitize_command_input(raw_user_command)
# Now safe to pass to subprocess or tool execution
Authentication and Rate Limiting
Restrict access using the authentication providers in src/security/auth.py. Configure either WhitelistAuthProvider (restricting by Telegram user ID) or TokenAuthProvider (API key validation). Set the ALLOWED_USERS environment variable to a comma-separated list of authorized Telegram IDs to prevent unauthenticated access.
Enable the RateLimiter middleware in src/security/rate_limiter.py to throttle requests. Tune the token-bucket parameters via environment variables (RATE_LIMIT, BURST_SIZE) to prevent brute-force attacks and denial-of-service flooding:
from src.security.rate_limiter import RateLimiter
import os
rate_limiter = RateLimiter(
max_requests=int(os.getenv("RATE_LIMIT", "10")),
window_seconds=int(os.getenv("RATE_WINDOW", "60"))
)
@rate_limiter.limit
async def handle_message(update, context):
# Process message with rate limiting applied
pass
Audit Logging and Monitoring
Keep the AuditLogger enabled (defined in src/security/audit.py) to record security-relevant events including file uploads, command execution attempts, and authentication failures. Store these logs in a persistent volume for post-incident analysis and configure alerting on failed validation attempts or directory traversal attacks detected by the middleware in src/bot/middleware/security.py.
Environment Configuration Best Practices
Load all settings through the Pydantic Settings class in src/config/settings.py. This centralizes configuration and provides type checking for critical security flags like DISABLE_SECURITY_PATTERNS.
- Use a
.envfile for local development but never commit real secrets; provide a.env.examplefile for documentation instead. - Run the bot inside a container with read-only filesystem mounts where possible.
- Mount only the
APPROVED_DIRECTORYvolume with write permissions; keep the application code read-only.
Summary
- Never disable security patterns (
DISABLE_SECURITY_PATTERNS=false) in production or publicly reachable deployments. - Lock down the filesystem by setting
APPROVED_DIRECTORYto a dedicated, restricted folder and validating all paths viaSecurityValidator. - Sanitize all inputs using
sanitize_command_input()before shell execution and validate filenames against theALLOWED_EXTENSIONSwhitelist. - Control access using
WhitelistAuthProviderorTokenAuthProviderwith a restrictedALLOWED_USERSlist. - Throttle traffic with the
RateLimitermiddleware to prevent abuse. - Enable audit logging to track file operations and authentication attempts for forensic analysis.
Frequently Asked Questions
What does DISABLE_SECURITY_PATTERNS actually disable?
When set to true, this flag skips the regex validation in src/security/validators.py that normally checks for dangerous characters like .., $(), ;, &&, and |. This removes protection against command injection and path traversal attacks, allowing raw user input to reach the filesystem or shell without sanitization.
Is it ever safe to disable security patterns?
Only in completely isolated, trusted environments such as sandboxed CI runners or local development containers where you control 100% of the input. Even then, the container must have no mounts to sensitive host directories outside APPROVED_DIRECTORY. Never disable this flag when the bot is accessible by untrusted Telegram users or on public servers.
How do I restrict which users can access the bot?
Configure the ALLOWED_USERS environment variable with a comma-separated list of authorized Telegram user IDs, and instantiate WhitelistAuthProvider from src/security/auth.py. Alternatively, use TokenAuthProvider to require an API key for access. Unauthenticated requests will be rejected before reaching the message handlers.
What happens if a user tries to upload a forbidden file type?
The validate_filename method in src/security/validators.py checks the extension against ALLOWED_EXTENSIONS and the name against FORBIDDEN_FILENAMES. If the file is rejected, the method returns (False, error_message) and the bot should discard the upload without writing to disk, logging the attempt via the AuditLogger for security review.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →