From 23dbbf26e3068e987301833524297f22f0aa1bbe Mon Sep 17 00:00:00 2001 From: ari melody Date: Fri, 7 Feb 2025 16:54:36 +0000 Subject: [PATCH] handle x-forwarded-for in IP logs --- admin/accounthttp.go | 6 +++--- admin/http.go | 12 ++++++------ controller/config.go | 1 + controller/ip.go | 10 ++++++---- model/appstate.go | 1 + 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/admin/accounthttp.go b/admin/accounthttp.go index fc03d77..125abdc 100644 --- a/admin/accounthttp.go +++ b/admin/accounthttp.go @@ -115,7 +115,7 @@ func changePasswordHandler(app *model.AppState) http.Handler { return } - app.Log.Info(log.TYPE_ACCOUNT, "\"%s\" changed password by user request. (%s)", session.Account.Username, controller.ResolveIP(r)) + app.Log.Info(log.TYPE_ACCOUNT, "\"%s\" changed password by user request. (%s)", session.Account.Username, controller.ResolveIP(app, r)) controller.SetSessionError(app.DB, session, "") controller.SetSessionMessage(app.DB, session, "Password updated successfully.") @@ -145,7 +145,7 @@ func deleteAccountHandler(app *model.AppState) http.Handler { // check password if err := bcrypt.CompareHashAndPassword([]byte(session.Account.Password), []byte(r.Form.Get("password"))); err != nil { - app.Log.Warn(log.TYPE_ACCOUNT, "Account \"%s\" attempted account deletion with incorrect password. (%s)", session.Account.Username, controller.ResolveIP(r)) + app.Log.Warn(log.TYPE_ACCOUNT, "Account \"%s\" attempted account deletion with incorrect password. (%s)", session.Account.Username, controller.ResolveIP(app, r)) controller.SetSessionError(app.DB, session, "Incorrect password.") http.Redirect(w, r, "/admin/account", http.StatusFound) return @@ -159,7 +159,7 @@ func deleteAccountHandler(app *model.AppState) http.Handler { return } - app.Log.Info(log.TYPE_ACCOUNT, "Account \"%s\" deleted by user request. (%s)", session.Account.Username, controller.ResolveIP(r)) + app.Log.Info(log.TYPE_ACCOUNT, "Account \"%s\" deleted by user request. (%s)", session.Account.Username, controller.ResolveIP(app, r)) controller.SetSessionAccount(app.DB, session, nil) controller.SetSessionError(app.DB, session, "") diff --git a/admin/http.go b/admin/http.go index c70dd1d..b16c209 100644 --- a/admin/http.go +++ b/admin/http.go @@ -201,7 +201,7 @@ func registerAccountHandler(app *model.AppState) http.Handler { return } - app.Log.Info(log.TYPE_ACCOUNT, "Account \"%s\" (%s) created using invite \"%s\". (%s)", account.Username, account.ID, invite.Code, controller.ResolveIP(r)) + app.Log.Info(log.TYPE_ACCOUNT, "Account \"%s\" (%s) created using invite \"%s\". (%s)", account.Username, account.ID, invite.Code, controller.ResolveIP(app, r)) err = controller.DeleteInvite(app.DB, invite.Code) if err != nil { @@ -277,7 +277,7 @@ func loginHandler(app *model.AppState) http.Handler { err = bcrypt.CompareHashAndPassword([]byte(account.Password), []byte(password)) if err != nil { - app.Log.Warn(log.TYPE_ACCOUNT, "\"%s\" attempted login with incorrect password. (%s)", account.Username, controller.ResolveIP(r)) + app.Log.Warn(log.TYPE_ACCOUNT, "\"%s\" attempted login with incorrect password. (%s)", account.Username, controller.ResolveIP(app, r)) controller.SetSessionError(app.DB, session, "Invalid username or password.") render() return @@ -305,7 +305,7 @@ func loginHandler(app *model.AppState) http.Handler { // login success! // TODO: log login activity to user - app.Log.Info(log.TYPE_ACCOUNT, "\"%s\" logged in. (%s)", account.Username, controller.ResolveIP(r)) + app.Log.Info(log.TYPE_ACCOUNT, "\"%s\" logged in. (%s)", account.Username, controller.ResolveIP(app, r)) app.Log.Warn(log.TYPE_ACCOUNT, "\"%s\" does not have any TOTP methods assigned.", account.Username) err = controller.SetSessionAccount(app.DB, session, account) @@ -363,7 +363,7 @@ func loginTOTPHandler(app *model.AppState) http.Handler { totpCode := r.FormValue("totp") if len(totpCode) != controller.TOTP_CODE_LENGTH { - app.Log.Warn(log.TYPE_ACCOUNT, "\"%s\" failed login (Invalid TOTP). (%s)", session.AttemptAccount.Username, controller.ResolveIP(r)) + app.Log.Warn(log.TYPE_ACCOUNT, "\"%s\" failed login (Invalid TOTP). (%s)", session.AttemptAccount.Username, controller.ResolveIP(app, r)) controller.SetSessionError(app.DB, session, "Invalid TOTP.") render() return @@ -377,13 +377,13 @@ func loginTOTPHandler(app *model.AppState) http.Handler { return } if totpMethod == nil { - app.Log.Warn(log.TYPE_ACCOUNT, "\"%s\" failed login (Invalid TOTP). (%s)", session.AttemptAccount.Username, controller.ResolveIP(r)) + app.Log.Warn(log.TYPE_ACCOUNT, "\"%s\" failed login (Invalid TOTP). (%s)", session.AttemptAccount.Username, controller.ResolveIP(app, r)) controller.SetSessionError(app.DB, session, "Invalid TOTP.") render() return } - app.Log.Info(log.TYPE_ACCOUNT, "\"%s\" logged in with TOTP method \"%s\". (%s)", session.AttemptAccount.Username, totpMethod.Name, controller.ResolveIP(r)) + app.Log.Info(log.TYPE_ACCOUNT, "\"%s\" logged in with TOTP method \"%s\". (%s)", session.AttemptAccount.Username, totpMethod.Name, controller.ResolveIP(app, r)) err = controller.SetSessionAccount(app.DB, session, session.AttemptAccount) if err != nil { diff --git a/controller/config.go b/controller/config.go index 8772b6b..5a69d49 100644 --- a/controller/config.go +++ b/controller/config.go @@ -21,6 +21,7 @@ func GetConfig() model.Config { BaseUrl: "https://arimelody.me", Host: "0.0.0.0", Port: 8080, + TrustedProxies: []string{ "127.0.0.1" }, DB: model.DBConfig{ Host: "127.0.0.1", Port: 5432, diff --git a/controller/ip.go b/controller/ip.go index 4b1126d..ae9d587 100644 --- a/controller/ip.go +++ b/controller/ip.go @@ -1,19 +1,21 @@ package controller import ( + "arimelody-web/model" "net/http" "slices" + "strings" ) // Returns the request's original IP address, resolving the `x-forwarded-for` // header if the request originates from a trusted proxy. -func ResolveIP(r *http.Request) string { - trustedProxies := []string{ "10.4.20.69" } - if slices.Contains(trustedProxies, r.RemoteAddr) { +func ResolveIP(app *model.AppState, r *http.Request) string { + addr := strings.Split(r.RemoteAddr, ":")[0] + if slices.Contains(app.Config.TrustedProxies, addr) { forwardedFor := r.Header.Get("x-forwarded-for") if len(forwardedFor) > 0 { return forwardedFor } } - return r.RemoteAddr + return addr } diff --git a/model/appstate.go b/model/appstate.go index 2516b6e..233e0db 100644 --- a/model/appstate.go +++ b/model/appstate.go @@ -26,6 +26,7 @@ type ( Host string `toml:"host"` Port int64 `toml:"port"` DataDirectory string `toml:"data_dir"` + TrustedProxies []string `toml:"trusted_proxies"` DB DBConfig `toml:"db"` Discord DiscordConfig `toml:"discord"` }