Major additions: - Community Next.js app (port 18187) for browsing claims with API docs - stemedb-chaos crate: Fault injection, chaos testing, CRDT properties - Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents - Disputed claims handling: Manual review workflows and validation - Aphoria security scanner: New extractors (SQL injection, command injection, weak crypto, TLS version), policy-based ignores, UAT reports - Docker infrastructure: Dockerfile, docker-compose.yml for full stack - VulnBank demo: Intentionally vulnerable multi-language test corpus SDK & API enhancements: - Source registry handlers for tracking data provenance - Metrics endpoint - Skeptic filtering improvements Code quality: - Split 14 large files (>500 lines) into focused modules - All files now under 500-line limit per project guidelines Documentation: - Chaos testing guide, circuit breakers, observability docs - Phase 7 UAT documentation updates - Martin Kleppmann technical writer agent Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
73 lines
1.9 KiB
Python
73 lines
1.9 KiB
Python
"""
|
|
VulnBank - Command Execution with intentional vulnerabilities
|
|
|
|
Vulnerabilities:
|
|
- Command injection via shell=True
|
|
- Command injection via os.system
|
|
"""
|
|
|
|
import subprocess
|
|
import os
|
|
|
|
|
|
def list_files(directory: str) -> str:
|
|
"""
|
|
VULNERABILITY: Command injection via shell=True
|
|
User input passed directly to shell command
|
|
"""
|
|
# BLOCK: shell=True with user input enables command injection
|
|
result = subprocess.run(
|
|
f"ls -la {directory}",
|
|
shell=True,
|
|
capture_output=True,
|
|
text=True
|
|
)
|
|
return result.stdout
|
|
|
|
|
|
def count_lines(filename: str) -> int:
|
|
"""
|
|
VULNERABILITY: Command injection via os.system
|
|
User-controlled filename in system command
|
|
"""
|
|
# BLOCK: os.system with user input enables command injection
|
|
os.system(f"wc -l {filename}")
|
|
return 0 # os.system doesn't capture output
|
|
|
|
|
|
def process_file(path: str) -> str:
|
|
"""
|
|
VULNERABILITY: Command injection via subprocess with shell
|
|
"""
|
|
# BLOCK: Command injection via Popen with shell=True
|
|
proc = subprocess.Popen(
|
|
f"cat {path} | head -10",
|
|
shell=True,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE
|
|
)
|
|
stdout, _ = proc.communicate()
|
|
return stdout.decode()
|
|
|
|
|
|
def backup_database(backup_name: str) -> bool:
|
|
"""
|
|
VULNERABILITY: Command injection in database backup
|
|
Attacker can execute arbitrary commands
|
|
"""
|
|
# BLOCK: Command injection - attacker controls backup filename
|
|
cmd = f"pg_dump vulnbank > /backups/{backup_name}.sql"
|
|
return os.system(cmd) == 0
|
|
|
|
|
|
# Safe version for comparison
|
|
def list_files_safe(directory: str) -> str:
|
|
"""Safe version using subprocess with list arguments"""
|
|
# This is the correct approach - no shell, list of arguments
|
|
result = subprocess.run(
|
|
["ls", "-la", directory],
|
|
capture_output=True,
|
|
text=True
|
|
)
|
|
return result.stdout
|