Dependabot alert #25 (python-jose algorithm confusion guard bypassed by
DER-encoded public keys, CVE-2026-85394, Critical) has no patched version
of python-jose available at all - it's affected through the latest
release 3.5.0. python-jose was only used in app/dependencies.py for plain
HS256 JWT encode/decode with our own symmetric SECRET_KEY (algorithms=[...]
was already explicitly restricted on every decode call, so the specific
RS256/HS256 confusion path didn't apply here), but staying on an
unmaintained library that keeps generating unfixable critical alerts isn't
sustainable.
Swapped to PyJWT, which is actively maintained, already pulled in
transitively via msal, and a near drop-in replacement for this app's
encode()/decode() usage. Verified with a Docker build and in-container
token create/verify/reject round-trip.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Bumps every flagged dependency to its patched (or latest compatible)
version: python-jose 3.3.0->3.4.0 (2 critical algorithm-confusion alerts),
cryptography 41.0.7->50.0.0 (7 alerts incl. a Bleichenbacher timing oracle
and outdated bundled OpenSSL), python-multipart 0.0.6->0.0.31 (9 alerts,
incl. a high-severity arbitrary file write), Jinja2 3.1.2->3.1.6 (5 sandbox
breakout / HTML injection alerts), and pytest 7.4.3->9.0.3 (1 alert,
dev-only).
msal had to move 1.28.0->1.39.0 because it pinned cryptography<45;
httpx had to move 0.26.0->0.28.1 and pytest-asyncio 0.23.2->1.4.0 and
pytest-httpx 0.28.0->0.36.2 to keep the dependency set resolvable
together with the above. Verified with a full Docker build and a running
container (health check, settings load, DB migrations all green).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Windows DNS (WinRM):
- New dns_service.py: create/delete A-records via PowerShell over WinRM (NTLM)
- Idempotent create (removes existing record first), graceful delete
- DNS failures are non-fatal — deployment continues, error logged
- test-dns endpoint: GET /api/settings/test-dns
- Integrated into deploy_customer() and undeploy_customer()
LDAP / Active Directory auth:
- New ldap_service.py: service-account bind + user search + user bind (ldap3)
- Optional AD group restriction via ldap_group_dn
- Login flow: LDAP first → local fallback (prevents admin lockout)
- LDAP users auto-created with auth_provider="ldap" and role="viewer"
- test-ldap endpoint: GET /api/settings/test-ldap
- reset-password/reset-mfa guards extended to block LDAP users
All credentials (dns_password, ldap_bind_password) encrypted with Fernet.
New DB columns added via backwards-compatible migrations.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Fix#1 - SECRET_KEY startup validation (config.py, .env):
- App refuses to start if SECRET_KEY is missing, shorter than 32 chars,
or matches a known insecure default value
- .env: replaced hardcoded test key with placeholder + generation hint
Fix#2 - Docker socket proxy (docker-compose.yml):
- Add tecnativa/docker-socket-proxy sidecar
- Only expose required Docker API endpoints (CONTAINERS, IMAGES,
NETWORKS, POST, EXEC); dangerous endpoints explicitly blocked
- Remove direct /var/run/docker.sock mount from main container
- Route Docker API via DOCKER_HOST=tcp://docker-socket-proxy:2375
Fix#3 - Azure AD group whitelist (auth.py, models.py, validators.py):
- New azure_allowed_group_id field in SystemConfig
- After token exchange, verify group membership via Graph API /me/memberOf
- Deny login with HTTP 403 if user is not in the required group
- New Azure AD users now get role 'viewer' instead of 'admin'
Fix#4 - Rate limiting on login (main.py, auth.py, requirements.txt):
- Add slowapi==0.1.9 dependency
- Initialize SlowAPI limiter in main.py with 429 exception handler
- Apply 10 requests/minute limit per IP on /login and /mfa/verify
Global MFA toggle in Security settings, QR code setup on first login,
6-digit TOTP verification on subsequent logins. Azure AD users exempt.
Admins can reset user MFA. TOTP secrets encrypted at rest with Fernet.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Multi-language support (EN/DE) with i18n engine and language files
- Configurable branding (name, subtitle, logo) in Settings
- Global default language and per-user language preference
- User management router with CRUD endpoints
- Customer status sync on start/stop/restart
- Health check fixes: derive status from container state, remove broken wget healthcheck
- Caddy reverse proxy and dashboard env templates for customer stacks
- Updated README with real hardware specs, prerequisites, and new features
- Removed .claude settings (JWT tokens) and build artifacts from tracking
- Updated .gitignore for .claude/ and Windows artifacts
Co-Authored-By: Claude Opus 4.6 <[email protected]>