diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml index a1a834f6e..b905b84f9 100644 --- a/.gitea/workflows/ci-cd.yml +++ b/.gitea/workflows/ci-cd.yml @@ -101,6 +101,62 @@ jobs: bandit --version pytest --version + - name: Secret detection (detect-secrets) + shell: sh + run: | + set -eu + echo "=== Installing detect-secrets ===" + python3 -m pip install -q detect-secrets + detect-secrets --version + echo "" + echo "=== Running secret scan ===" + detect-secrets scan \ + --all-files \ + --exclude-files '(^|/)(tests|test|e2e|__tests__|spec|docs|node_modules|site-packages|migrations|alembic|.gitea|.git|.pytest_cache|.next|dist|build)/' \ + --exclude-files '\.(md|rst|txt|lock|example|sample|min\.js|min\.css|spec\.ts|test\.ts|test\.py)$' \ + --exclude-files '(package-lock|yarn\.lock|poetry\.lock|Pipfile\.lock)$' \ + --disable-plugin Base64HighEntropyString \ + --disable-plugin HexHighEntropyString \ + --disable-plugin BasicAuthDetector \ + --disable-plugin KeywordDetector \ + --disable-plugin IPPublicDetector \ + 2>&1 | tee /tmp/secrets-scan.json + + FOUND=$(python3 -c " + import json + try: + with open('/tmp/secrets-scan.json') as f: + data = json.load(f) + results = data.get('results', {}) + total = sum(len(v) for v in results.values()) + print(total) + except Exception: + print('error') + ") + echo "" + echo "Secrets detected: $FOUND" + if [ "$FOUND" != "0" ] && [ "$FOUND" != "error" ]; then + echo "" + echo "=== Secret details ===" + python3 -c " + import json + with open('/tmp/secrets-scan.json') as f: + data = json.load(f) + for fpath, items in data.get('results', {}).items(): + for item in items: + line = item.get('line_number', '?') + stype = item.get('type', '?') + hashed = item.get('hashed_secret', '')[:16] + print(f' {fpath}:{line} [{stype}] {hashed}...') + " + echo "" + echo "ERROR: Potential secrets detected in code!" + echo "If these are false positives, add exclusions in the CI workflow." + exit 1 + fi + echo "Secret scan completed - no secrets detected" + + - name: Run code quality checks shell: sh run: | @@ -110,12 +166,56 @@ jobs: python3 -m isort --check-only alembic apps packages tests scripts python3 -m flake8 apps packages tests --count --statistics - - name: Run security scan + - name: Run security scan (bandit) shell: sh run: | set -eu bandit -r apps packages -q -ll + - name: Python dependency vulnerability scan (pip-audit) + shell: sh + run: | + set -eu + echo "=== Installing pip-audit ===" + python3 -m pip install -q pip-audit + pip-audit --version + echo "" + echo "=== Scanning Python dependencies ===" + EXIT_CODE=0 + for req_file in requirements.txt requirements-base.txt requirements-dev.txt; do + if [ -f "$req_file" ]; then + echo "--- Scanning $req_file ---" + pip-audit -r "$req_file" --desc on 2>&1 | head -40 || EXIT_CODE=$? + echo "" + fi + done + echo "pip-audit scan completed (advisory mode - warnings only, not blocking CI)" + if [ "$EXIT_CODE" != "0" ]; then + echo "WARNING: Potential vulnerabilities found in dependencies." + fi + exit 0 + + - name: Dead code detection (vulture) + shell: sh + run: | + set -eu + echo "=== Installing vulture ===" + python3 -m pip install -q vulture + vulture --version + echo "" + echo "=== Running vulture dead code scan ===" + EXIT_CODE=0 + vulture apps packages scripts \ + --exclude "tests,test,migrations,.gitea,docs,node_modules,site-packages,*/test_*.py,*/conftest.py" \ + --min-confidence 80 \ + 2>&1 | head -60 || EXIT_CODE=$? + echo "" + echo "vulture scan completed (advisory mode - P2, for reference only)" + if [ "$EXIT_CODE" != "0" ]; then + echo "NOTE: Potential dead code found (may include false positives from framework code)." + fi + exit 0 + - name: Validate release scripts syntax shell: sh run: | diff --git a/.gitleaks.toml b/.gitleaks.toml deleted file mode 100644 index 41499d6cd..000000000 --- a/.gitleaks.toml +++ /dev/null @@ -1,52 +0,0 @@ -# .gitleaks.toml - gitleaks 白名单配置 -# 仓库: xiaoxia/xiaoxia-saas -# 用途: 排除已知的测试密钥、示例配置等误报 - -# 允许路径/文件排除 -[allowlist] -description = "全局白名单 - 排除示例配置和测试文件" -paths = [ - # 环境配置示例(无真实密钥) - '.env.example', - '.env.sample', - '*.env.example', - '*.env.sample', - # 测试文件 - 'tests/', - 'test/', - '*/tests/', - '*/test/', - # 文档 - 'docs/', - '*.md', - '*.rst', - # 前端依赖 - 'node_modules/', - # Python包 - 'site-packages/', - # 锁定文件(自动生成) - 'poetry.lock', - 'Pipfile.lock', - 'requirements*.txt.lock', - # CI配置本身 - '.gitea/', - # Docker相关 - 'docker-compose*.yml', - # gitleaks配置自身 - '.gitleaks.toml', -] - -# 允许的密钥值/占位符正则 -regexes = [ - # 占位符模式 - '''(?i)(your[_-]?password|your[_-]?secret|your[_-]?key|your[_-]?token|changeme|change[_-]?me|placeholder|example[_-]?key|test[_-]?key|dummy|fake|mock|xxx|none|not[_-]?set|TODO|FIXME)''', - # 数据库连接字符串中的通用密码(PostgreSQL示例配置) - '''postgresql://[^:]+:changeme@''', - '''postgresql://[^:]+:your-password@''', - '''postgresql://[^:]+:password@localhost''', - # Redis示例配置 - '''redis://:changeme@''', - '''redis://:your-redis-password@''', - # JWT示例密钥 - '''(?i)jwt[_-]?secret\s*[:=]\s*["']?(your[_-]?jwt|change|placeholder|secret|example)''', -] diff --git a/vulture.conf b/vulture.conf deleted file mode 100644 index 22ba44643..000000000 --- a/vulture.conf +++ /dev/null @@ -1,35 +0,0 @@ -# vulture.conf - 死代码检测配置 -# 仓库: xiaoxia/xiaoxia-saas -# 用途: 检测未使用的函数、变量、导入、类、方法、属性 - -# 扫描目录(空格分隔) -path = alembic apps packages scripts - -# 排除路径(每个路径一行,相对于仓库根目录) -exclude = - tests - test - */tests - */test - site-packages - node_modules - migrations - .gitea - docs - scripts/check_*.py - scripts/init_*.py - -# 最低置信度 (%) -# 0 = 报告所有可能的未使用代码 -# 100 = 只报告确定未使用的代码 -# 推荐从 80% 开始,逐步调高 -min-confidence = 80 - -# 输出格式: string, json, yaml -format = text - -# 按置信度排序 -sort-by-size = False - -# 显示置信度 -show-uncertain = True diff --git a/vulture_whitelist.py b/vulture_whitelist.py deleted file mode 100644 index 155f481b7..000000000 --- a/vulture_whitelist.py +++ /dev/null @@ -1,57 +0,0 @@ -# vulture_whitelist.py - vulture 白名单文件 -# 用途: 列出已知被框架/动态调用的代码,避免误报 -# 参考: https://vulture.readthedocs.io/en/stable/whitelists.html - -# FastAPI / Starlette 框架自动调用 -# FastAPI route handlers (通过装饰器注册,vulture 可能无法识别) -apps.*.main.* -apps.*.api.* -apps.*.routes.* -apps.*.views.* - -# SQLAlchemy ORM -# Model 类和字段通过 ORM 框架自动使用 -apps.*.models.* -apps.*.schemas.* -packages.*.models.* - -# Pydantic models -# Pydantic 字段通过序列化/反序列化使用 -apps.*.schemas.* -packages.*.schemas.* - -# Alembic migrations -# Migration 函数由 alembic 自动调用 -alembic.versions.*.upgrade -alembic.versions.*.downgrade - -# Celery tasks -# Task 函数通过 celery worker 调用 -apps.*.tasks.* -packages.*.tasks.* - -# CLI scripts / entry points -# 脚本通过命令行调用 -scripts.* - -# 中间件 -apps.*.middleware.* -packages.*.middleware.* - -# 异常类 -apps.*.exceptions.* -packages.*.exceptions.* - -# 配置类 -apps.*.config.* -packages.*.config.* - -# 工具函数(可能被多处间接调用,先白名单,后续清理) -apps.*.utils.* -packages.*.utils.* -apps.*.helpers.* -packages.*.helpers.* - -# Dependencies (FastAPI Depends) -apps.*.dependencies.* -packages.*.dependencies.*