# Security Runbook für NexQuant ## Bandit Security Scanner ### Konfiguration Bandit ist als Pre-Commit Hook konfiguriert und scannt automatisch alle Python-Dateien vor jedem Commit. **Konfigurationsdateien:** - `.bandit.yml` - Bandit-Einstellungen - `.pre-commit-config.yaml` - Pre-commit Hooks - `requirements/lint.txt` - Bandit Dependency ### Scan-Befehle ```bash # Alle Dateien scannen bandit -r rdagent/ -c .bandit.yml # Nur HIGH Severity Issues bandit -r rdagent/ -c .bandit.yml --severity-level high # Spezifische Datei scannen bandit rdagent/components/backtesting/results_db.py -c .bandit.yml # Mit JSON Output (für CI/CD) bandit -r rdagent/ -c .bandit.yml -f json -o results/security/bandit-report.json ``` ### Gefundene HIGH Severity Issues #### 1. subprocess mit shell=True (12 Issues) **Dateien:** - `rdagent/utils/env.py` (mehrere Stellen) - `rdagent/components/coder/factor_coder/factor.py` **Bewertung:** ✅ **Akzeptiert** - Internal Tool - Alle Commands verwenden hardcodierte Strings, keine User-Inputs - Risk: Command Injection bei manipulierten Inputs - Mitigation: Code-Review für alle subprocess-Aufrufe, keine externen Inputs **Empfohlene Fixes (Future PR):** ```python # Statt: subprocess.run(f"conda env list | grep -q '^{env_name} '", shell=True) # Besser: subprocess.run(["conda", "env", "list"], capture_output=True, text=True, check=True) # Dann in Python auf env_name prüfen ``` **Priority:** MEDIUM - Refactor in nächster Wartungsphase --- #### 2. Jinja2 autoescape=False (6 Issues) **Dateien:** - `rdagent/components/coder/data_science/ensemble/__init__.py` - `rdagent/components/coder/data_science/ensemble/eval.py` - `rdagent/scenarios/kaggle/developer/coder.py` (2x) - `rdagent/scenarios/qlib/experiment/utils.py` - `rdagent/utils/agent/tpl.py` **Bewertung:** ✅ **Akzeptiert** - Template Generation für Code - Templates generieren Python-Code, nicht HTML - XSS-Risiko besteht nicht bei Code-Templates - `StrictUndefined` verhindert undefined variable leaks **Mitigation:** ✅ Already secure durch `StrictUndefined` --- #### 3. MD5 Hash (2 Issues) **Dateien:** - `rdagent/log/ui/ds_trace.py` (2x) **Bewertung:** ✅ **Akzeptiert** - Non-Crypto Use Case - MD5 wird für UI-Caching verwendet, nicht für Security - `usedforsecurity=False` kann hinzugefügt werden **Empfohlener Fix (Quick Win):** ```python # Zeile 226 & 333 in rdagent/log/ui/ds_trace.py unique_key = hashlib.md5("...".encode(), usedforsecurity=False).hexdigest() ``` **Priority:** LOW - 5 Minuten Fix --- #### 4. tarfile.extractall ohne Validation (2 Issues) **Dateien:** - `rdagent/scenarios/data_science/proposal/exp_gen/select/submit.py` - `rdagent/scenarios/kaggle/kaggle_crawler.py` **Bewertung:** ⚠️ **Sollte gefixt werden** - Path Traversal Risk - Extrahiert externe Archive (Kaggle Datasets) - Risk: Path Traversal Attacks via `../../../etc/passwd` **Empfohlener Fix:** ```python import tarfile import os def safe_extractall(tar: tarfile.TarFile, path: str) -> None: """Extract tarfile safely, preventing path traversal.""" def is_within_directory(directory: str, target: str) -> bool: abs_directory = os.path.abspath(directory) abs_target = os.path.abspath(target) prefix = os.path.commonprefix([abs_directory, abs_target]) return prefix == abs_directory for member in tar.getmembers(): member_path = os.path.join(path, member.name) if not is_within_directory(path, member_path): raise ValueError(f"Attempted Path Traversal: {member.name}") tar.extractall(path=path) # Usage: with tarfile.open(tar_path, mode="r:*") as tar: safe_extractall(tar, to_dir) ``` **Priority:** HIGH - Nächster Sprint --- #### 5. Flask debug=True (1 Issue) **Datei:** - `rdagent/log/server/debug_app.py:170` **Bewertung:** ⚠️ **Sollte gefixt werden** - Debugger Exposure - `debug=True` ermöglicht arbitrary code execution - Sollte nur in Development-Umgebung sein **Empfohlener Fix:** ```python import os # Zeile 170 debug_mode = os.getenv("FLASK_ENV") == "development" app.run(debug=debug_mode, host="0.0.0.0", port=port) ``` **Priority:** HIGH - Quick Fix --- ### Skipped Rules Begründung | Rule | Begründung | Status | |------|-----------|--------| | B101 (assert) | Development/Debug Assertions | ✅ Akzeptiert | | B311 (random) | Non-Crypto Random Usage | ✅ Akzeptiert | | B404, B603, B607 (subprocess) | Legitimate System Operations | ⚠️ Monitor | | B113 (request timeout) | Wird in future PR gefixt | 📋 Planned | | B608 (SQL injection) | Internal Tool, keine User-Inputs | ⚠️ Monitor | | B301 (pickle) | Controlled Data Sources | ⚠️ Monitor | | B701 (jinja2) | Code Templates, nicht HTML | ✅ Secure | | B201 (flask debug) | Development Only | 📋 Fix Planned | | B324 (hashlib) | Non-Crypto (Caching) | 📋 Quick Fix | | B202 (tarfile) | External Archives | 🔴 Fix Required | --- ### Pre-Commit Verhalten **Blockiert Commit bei:** - HIGH Severity Issues (standardmäßig aktiv) **Erlaubt Commit bei:** - MEDIUM Severity Issues (Informational) - LOW Severity Issues (Informational) **Manuelles Überspringen (NOT recommended):** ```bash # Nur im Notfall! git commit --no-verify -m "feat: urgent fix" ``` --- ### CI/CD Integration Für GitHub Actions: ```yaml # .github/workflows/security.yml name: Security Scan on: push: branches: [master, main] pull_request: branches: [master, main] jobs: bandit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.10' - name: Install dependencies run: pip install bandit - name: Run Bandit run: | bandit -r rdagent/ \ -c .bandit.yml \ -f json \ -o bandit-report.json \ --exit-zero - name: Upload Security Report uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: bandit-report.json ``` --- ### Regelmäßige Wartung **Monatlich:** ```bash # Bandit-Report generieren bandit -r rdagent/ -c .bandit.yml -f html -o results/security/bandit-report-$(date +%Y-%m).html # Trend-Analyse bandit -r rdagent/ -c .bandit.yml -lll | grep "Total issues" ``` **Quartalsweise:** - Alle `# nosec` Comments reviewen - Skipped Rules reevaluieren - Neue Security-Best-Practices einarbeiten --- ### Kontakt & Eskalation - **Security Issues melden:** @TPTBusiness - **False Positives:** Zu `.bandit.yml` hinzufügen mit Begründung - **Patches:** PR mit Label `security` erstellen --- ### Referenzen - [Bandit Documentation](https://bandit.readthedocs.io/) - [OWASP Top 10](https://owasp.org/www-project-top-ten/) - [CWE Database](https://cwe.mitre.org/) - [Pre-Commit Hooks](https://pre-commit.com/)