checkin() und downloadSetup() liefern jetzt nie eine ältere Version aus,
als der Agent laut DB/eigenem Report bereits installiert hat (clampToNotOlder).
Schützt gegen genau den Bug von heute (kaputte AGENT_VERSION env-Var führte
zu echtem Downgrade auf v2.0.0 bei 17 Agents) — selbst bei künftigen
Konfigurationsfehlern kann der Server keinen Downgrade mehr anstoßen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Beim heutigen Secrets-Cleanup von docker-compose.yml ging AGENT_VERSION
verloren (war nur ad-hoc auf dem Server gesetzt, nie versioniert) — der
Code-Fallback griff dadurch wieder auf hartcodierte Alt-Versionen zurück
('2.0.0'/'1.2.4'/'1.2.3'), wodurch 17 Agents beim Selbst-Update-Versuch
fälschlich auf v2.0.0 downgraded wurden. AGENT_VERSION jetzt fest im
docker-compose.yml-Template verankert, alle Fallback-Stellen im Code auf
eine gemeinsame FALLBACK_AGENT_VERSION-Konstante zusammengeführt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Agent v2.8.0 tauscht beim Start automatisch den geteilten Bootstrap-Key
gegen einen individuellen Per-Device-Key (POST /api/monitoring/enroll,
idempotent). Checkin/Announcements-Poll/Setup-Download/WS-Agent-Verbindungen
validieren den Key jetzt gegen den jeweiligen Hostname — ein gestohlener
Key kann sich nicht mehr als anderer Agent ausgeben (manuell verifiziert).
Alte Agents mit dem geteilten Key funktionieren während der Übergangsphase
weiter (validateAgentKey() akzeptiert beides), damit der Rollout die Fleet
nicht abrupt bricht — Migration läuft über den bestehenden Staged-Rollout
(Test → Pilot → Produktion).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docker-compose.yml lag mit allen Produktions-Secrets im Klartext im Repo
(JWT_SECRET, Anthropic-API-Key, Azure-Client-Secret, SMTP/IMAP-Passwort,
Proxmox-/GitHub-Token, Teams-Bot-Secret) — bereits vor diesem Repo in der
GitHub-History vorhanden, jetzt auf ENV-Variablen umgestellt. Echte Werte
liegen jetzt nur noch in einer .env auf dem Server (gitignored).
JWT_SECRET wurde rotiert (rein intern, erzwingt einmaliges Neu-Login).
AGENT_API_KEY und SCANNER_API_KEY bewusst NICHT rotiert, da das sofort die
gesamte Agent-/Scanner-Fleet brechen würde — wird zusammen mit der geplanten
Umstellung auf pro-Geräte-Keys gemacht. Externe Secrets (Anthropic, Azure,
Proxmox, GitHub, M365-Mailbox) müssen von Simon manuell in den jeweiligen
Portalen rotiert werden, da kein Tool-Zugriff von hier aus möglich ist.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Entfernt aus der Versionierung (bleibt lokal auf der Platte, nicht Teil der IT-Nexus-App):
domain-join-tool/, nexus-scanner/ (separates Go-Projekt), playwright-tests/,
alte PS1-Agent-Generation (agent/), .claude/, .github/workflows/, diverse
Demo-HTMLs/.docx/.zip-Altlasten im Root.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- WebSocket Shell/RDP: Rollenprüfung statt nur JWT-Gültigkeit (war: jeder eingeloggte User konnte fremde Agents per Shell/RDP übernehmen)
- JWT_SECRET: Server bricht ab statt mit unsicherem Default weiterzulaufen
- Auth: Token läuft jetzt über httpOnly-Cookie statt localStorage (XSS-Schutz gegen Session-Diebstahl)
- WS-Auth: Token nicht mehr als URL-Query-Param (landete in nginx-Logs), sondern als erste Message bzw. automatisch via Cookie
- Frontend: toter Rollen-Check (isSuperAdmin/isAdmin ohne Funktionsaufruf) in AgentDetailPage gefixt
- XSS: DOMPurify-Sanitizing für alle marked.parse()-Renderstellen (KI-Antworten, Kommentare, Knowledge Base)
- E-Mail: HTML-Escaping für alle ticket-gesteuerten Felder (auch über öffentliche Ticket-Route erreichbar)
- SSRF-Schutz beim Knowledge-Base-URL-Import (blockt private/Loopback-Adressen)
- TV-Dashboard: Shared-Key statt komplett offenem Endpoint
- Striktes Rate-Limit auf /login, must_change_password serverseitig erzwungen
- Agent (C#) v2.7.0: RDP-Consent/Disconnect/Capture verlangen jetzt ein Pro-Session-Secret (war: jeder lokale Prozess konnte Consent vortäuschen), DataDir-ACL für agent.log/status.json
- FIDO-PINs AES-256-GCM-verschlüsselt statt Klartext, Retention-Job für alte patch_commands/audit_log
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- RdpActiveIndicatorWindow: TeamViewer-Style Overlay unten rechts, solange
RDP-Capture läuft. Zeigt Dauer der Sitzung + pulsierenden roten Punkt
- User kann per "Trennen"-Button selbst die Sitzung beenden (TCP-Signal
an Service, cancelt Capture-Loop sofort — auch nach Screen-Wechsel)
- Overlay läuft als separater User-Prozess via SessionSpawner, wird vom
Service direkt gekillt wenn Sitzung endet (rdp_stop oder Disconnect)
- Version: 2.5.0 → 2.6.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- dotnet publish lief zuvor mit --self-contained false → Installer nur 2MB
ohne .NET-Runtime, schlägt auf Rechnern ohne .NET 8 fehl. Jetzt wieder
self-contained Single-File wie historische Versionen (~53MB)
- setup.iss: Vor Installation werden jetzt automatisch verwaiste
IT-Nexus-Agent.exe Prozesse gekillt und Reste eines laufenden
Self-Update-Zyklus (update.cmd, heruntergeladener Installer) entfernt
- Behebt Installations-Instabilität durch File-Locks bei Upgrades
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- downloadSetup() nutzte process.env.AGENT_VERSION statt der Patch-Gruppen-
Zielversion → Staged Rollout (Test/Pilot/Produktion) hatte nie funktioniert,
jeder Agent bekam beim Auto-Update immer dieselbe globale Version
- Fix: downloadSetup() löst jetzt per ?hostname=X die Gruppen-Zielversion auf,
exakt wie checkin() es bereits tat
- ApiService.DownloadSetupAsync() schickt jetzt den Hostnamen mit
- Version: 2.4.0 → 2.5.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NVD API unterstützt keine kombinierten Filter (Timeout bei cvssV3Severity+pubStartDate).
Lösung: Erst totalResults holen, dann die letzten 60 Einträge mit startIndex abrufen
und lokal nach Score >= 5 / High+Critical filtern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Agent sends rdp_consent_pending after spawning consent dialog
- Browser shows 'Warte auf Zustimmung...' with yellow indicator
- First frame switches to 'connected', denial shows red error message
- Fixed stale closure bug in onmessage with connectedRef
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When rdp_start arrives, agent first spawns a WPF consent dialog in the
user session (via schtasks). User has 30s to accept or deny. On deny,
agent sends rdp_denied to browser which shows "Zugriff abgelehnt".
On accept, screen capture starts as before.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pipeName[^8..] crashed for 5-char port strings (e.g. "54321").
Now uses port number directly as task name suffix.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Named pipe created by SYSTEM service denied connection from user process.
TCP loopback socket (127.0.0.1:random) has no cross-session ACL issues.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CaptureModeRunner: captures desktop in user session via schtasks,
sends JPEG frames over named pipe to service
- RtcService: creates named pipe server, spawns helper via schtasks
(same pattern as NotificationService), reads frames and forwards to WS
- Program.cs: added --rdp-capture <pipeName> mode
- Multi-monitor: captures all screens combined
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>