Rename all source files, scripts, tests, documentation, and configuration from Predix/predix to NexQuant/nexquant across the entire codebase.
6.7 KiB
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 Hooksrequirements/lint.txt- Bandit Dependency
Scan-Befehle
# 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):
# 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__.pyrdagent/components/coder/data_science/ensemble/eval.pyrdagent/scenarios/kaggle/developer/coder.py(2x)rdagent/scenarios/qlib/experiment/utils.pyrdagent/utils/agent/tpl.py
Bewertung: ✅ Akzeptiert - Template Generation für Code
- Templates generieren Python-Code, nicht HTML
- XSS-Risiko besteht nicht bei Code-Templates
StrictUndefinedverhindert 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=Falsekann hinzugefügt werden
Empfohlener Fix (Quick Win):
# 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.pyrdagent/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:
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=Trueermöglicht arbitrary code execution- Sollte nur in Development-Umgebung sein
Empfohlener Fix:
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):
# Nur im Notfall!
git commit --no-verify -m "feat: urgent fix"
CI/CD Integration
Für GitHub Actions:
# .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:
# 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
# nosecComments reviewen - Skipped Rules reevaluieren
- Neue Security-Best-Practices einarbeiten
Kontakt & Eskalation
- Security Issues melden: @TPTBusiness
- False Positives: Zu
.bandit.ymlhinzufügen mit Begründung - Patches: PR mit Label
securityerstellen