From 2046f6475b55d68f146b3c6b0f2e561a1da98df8 Mon Sep 17 00:00:00 2001 From: patrick Date: Wed, 5 Aug 2026 19:10:28 +0200 Subject: [PATCH] fix(security): python-jose CVE-2024-33663 durch pyjwt ersetzt, Deps gepinnt - security.py/dependencies.py/auth.py: jose -> pyjwt (unmaintained, Algorithm-Confusion-CVE). API-kompatibel (jwt.encode/decode gleich). - requirements.txt: alle Versionen gepinnt (waren >=, jetzt == anhand aktueller 137-Installation) fuer reproduzierbare Deploys. - nginx.conf: /docs + /openapi.json nur noch aus LAN erreichbar (waren oeffentlich, API-Struktur-Leak). fail2ban auf 137+164 installiert (sshd + nginx-badbots + timemaster-auth Jails), Configs nicht im Repo (Server-only, /etc/fail2ban/). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01LTxkZEUdfgMxZvHPiZJ8bV --- DEVLOG.md | 36 ++++++++++++++++++++ backend/app/core/dependencies.py | 2 +- backend/app/core/security.py | 3 +- backend/app/routers/auth.py | 2 +- backend/requirements.txt | 58 ++++++++++++++++---------------- nginx.conf | 11 +++++- 6 files changed, 79 insertions(+), 33 deletions(-) diff --git a/DEVLOG.md b/DEVLOG.md index 4085703..fda8be2 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -2686,3 +2686,39 @@ Keine Commits in dieser Session. - frontend/src/types/hoursPayout.ts | 7 ++ --- +## 2026-08-05 18:56 – 18:57 (0m) +**Beschreibung:** Claude Code Session +**Projekt:** timemaster + +### Commits +- 803e888 fix(hours_payouts): RLS-Bypass-Falle bei mid-request commit + +### Geänderte Dateien +- DEVLOG.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ +- backend/app/routers/hours_payouts.py | 22 ++++++++++++---------- + +--- +## 2026-08-05 18:57 – 18:57 (0m) +**Beschreibung:** Claude Code Session +**Projekt:** timemaster + +### Commits +Keine Commits in dieser Session. + +### Geänderte Dateien +- DEVLOG.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ +- backend/app/routers/hours_payouts.py | 22 ++++++++++++---------- + +--- +## 2026-08-05 18:58 – 18:58 (0m) +**Beschreibung:** Claude Code Session +**Projekt:** timemaster + +### Commits +Keine Commits in dieser Session. + +### Geänderte Dateien +- DEVLOG.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ +- backend/app/routers/hours_payouts.py | 22 ++++++++++++---------- + +--- diff --git a/backend/app/core/dependencies.py b/backend/app/core/dependencies.py index c528f2b..ff26980 100644 --- a/backend/app/core/dependencies.py +++ b/backend/app/core/dependencies.py @@ -4,7 +4,7 @@ from uuid import UUID from fastapi import Depends, HTTPException, Request, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer -from jose import JWTError +from jwt import PyJWTError as JWTError from sqlalchemy import text from sqlalchemy.ext.asyncio import AsyncSession diff --git a/backend/app/core/security.py b/backend/app/core/security.py index 189298c..03eabfc 100644 --- a/backend/app/core/security.py +++ b/backend/app/core/security.py @@ -4,7 +4,8 @@ import secrets import hashlib import bcrypt -from jose import JWTError, jwt +import jwt +from jwt import PyJWTError as JWTError from app.core.config import settings diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py index 62534ec..dcaab51 100644 --- a/backend/app/routers/auth.py +++ b/backend/app/routers/auth.py @@ -306,7 +306,7 @@ async def totp_login( from app.core.config import settings from app.core.security import decode_partial_token from app.models.user import User - from jose import JWTError + from jwt import PyJWTError as JWTError try: user_id = decode_partial_token(data.partial_token) diff --git a/backend/requirements.txt b/backend/requirements.txt index 62febba..d9a50ec 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,29 +1,29 @@ -fastapi>=0.110.0 -uvicorn[standard]>=0.27.0 -sqlalchemy[asyncio]>=2.0.0 -asyncpg>=0.29.0 -alembic>=1.13.0 -pydantic[email]>=2.6.0 -pydantic-settings>=2.2.0 -python-jose[cryptography]>=3.3.0 -bcrypt>=4.0.0 -openpyxl>=3.1.0 -ldap3>=2.9.0 -cryptography>=42.0.0 -python-multipart>=0.0.9 -slowapi>=0.1.9 -limits>=3.6.0 -redis>=5.0.0 -resend>=0.7.0 -python-dateutil>=2.9.0 -pyotp>=2.9.0 -httpx>=0.27.0 -icalendar>=5.0.0 -pytest>=8.0.0 -pytest-asyncio>=0.23.0 -pytest-httpx>=0.30.0 -aiosqlite>=0.20.0 -weasyprint>=61.0 -typer>=0.12.0 -rich>=13.7.0 -apscheduler>=3.10.0 +fastapi==0.135.2 +uvicorn[standard]==0.42.0 +sqlalchemy[asyncio]==2.0.48 +asyncpg==0.31.0 +alembic==1.18.4 +pydantic[email]==2.12.5 +pydantic-settings==2.13.1 +pyjwt[crypto]==2.10.1 +bcrypt==5.0.0 +openpyxl==3.1.5 +ldap3==2.9.1 +cryptography==46.0.6 +python-multipart==0.0.22 +slowapi==0.1.9 +limits==5.8.0 +redis==7.4.0 +resend==2.26.0 +python-dateutil==2.9.0.post0 +pyotp==2.9.0 +httpx==0.28.1 +icalendar==7.0.3 +pytest==9.0.2 +pytest-asyncio==1.3.0 +pytest-httpx==0.36.0 +aiosqlite==0.22.1 +weasyprint==68.1 +typer==0.25.1 +rich==15.0.0 +apscheduler==3.11.2 diff --git a/nginx.conf b/nginx.conf index 80ece8d..99985b1 100644 --- a/nginx.conf +++ b/nginx.conf @@ -30,8 +30,13 @@ server { add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none';" always; } - # FastAPI Docs (nur in dev aktiv) + # FastAPI Docs – nur aus internem LAN erreichbar (API-Struktur sonst für + # Angreifer sichtbar). LAN-Bereich ggf. an tatsächliches Subnetz anpassen. location /docs { + allow 192.168.1.0/24; + allow 127.0.0.1; + deny all; + proxy_pass http://127.0.0.1:8000/docs; # Security Headers @@ -44,6 +49,10 @@ server { } location /openapi.json { + allow 192.168.1.0/24; + allow 127.0.0.1; + deny all; + proxy_pass http://127.0.0.1:8000/openapi.json; # Security Headers