fix(security): W-02 Secure-Cookie-Flag + W-03 TrustedProxies für X-Forwarded-For

W-02: Cookie Secure-Flag ist nun über config.yml steuerbar.
      api.secure_cookies: true/false — default false (kein Breaking Change).
      Alle 3 SetCookie-Aufrufe (Login, Logout, TOTP) nutzen s.cfg.SecureCookies.

W-03: remoteIP() ist jetzt eine Methode und prüft api.trusted_proxies.
      X-Forwarded-For wird nur ausgewertet wenn der direkte Peer in der
      trusted_proxies-Liste steht (IP oder CIDR). Sonst wird r.RemoteAddr
      verwendet — kein Spoofing mehr möglich.
      Neue Hilfsfunktion: isTrustedProxy(ip, proxies).

config.go: APIConfig um SecureCookies bool + TrustedProxies []string erweitert.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-03-18 01:10:24 +01:00
parent 280034679e
commit 0fbb1924bb
6 changed files with 74 additions and 39 deletions
+11 -11
View File
@@ -81,7 +81,7 @@ func (s *Server) handleSaveLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "ldap_config_saved",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: true,
Detail: "LDAP-Konfiguration gespeichert",
})
@@ -109,7 +109,7 @@ func (s *Server) handleDeleteLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "ldap_config_deleted",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: true,
Detail: "LDAP-Konfiguration gelöscht",
})
@@ -167,7 +167,7 @@ func (s *Server) handleTestLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "ldap_connection_test",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: result.OK,
Detail: result.Message,
})
@@ -218,7 +218,7 @@ func (s *Server) handleCreateTenant(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "tenant_created",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant erstellt: " + req.Name,
})
@@ -308,7 +308,7 @@ func (s *Server) handleDeleteTenant(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "tenant_deleted",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant gelöscht: " + strconv.FormatInt(id, 10),
})
@@ -469,7 +469,7 @@ func (s *Server) handleSaveTenantLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_config_saved",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-LDAP-Konfiguration gespeichert",
})
@@ -500,7 +500,7 @@ func (s *Server) handleDeleteTenantLDAP(w http.ResponseWriter, r *http.Request)
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_config_deleted",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-LDAP-Konfiguration gelöscht",
})
@@ -539,7 +539,7 @@ func (s *Server) handleTestTenantLDAP(w http.ResponseWriter, r *http.Request) {
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_connection_test",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: result.OK,
Detail: result.Message,
})
@@ -611,7 +611,7 @@ func (s *Server) handleAdminSaveTenantLDAP(w http.ResponseWriter, r *http.Reques
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_config_saved",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-LDAP-Konfiguration gespeichert (tenant " + strconv.FormatInt(id, 10) + ")",
})
@@ -643,7 +643,7 @@ func (s *Server) handleAdminDeleteTenantLDAP(w http.ResponseWriter, r *http.Requ
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_config_deleted",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: true,
Detail: "Mandant-LDAP-Konfiguration gelöscht (tenant " + strconv.FormatInt(id, 10) + ")",
})
@@ -683,7 +683,7 @@ func (s *Server) handleAdminTestTenantLDAP(w http.ResponseWriter, r *http.Reques
s.audlog.Log(audit.Entry{
EventType: "tenant_ldap_connection_test",
Username: sess.Username,
IPAddress: remoteIP(r),
IPAddress: s.remoteIP(r),
Success: result.OK,
Detail: result.Message + " (tenant " + strconv.FormatInt(id, 10) + ")",
})