diff options
| author | historia <[not public]> | 2026-09-18 15:42:23 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-18 15:42:23 -0400 |
| commit | 67e01aab85607b9e601185c7d62dff576af3bb43 (patch) | |
| tree | 059134b2434eba7c14aa9d89f48c5a475feb0312 /internal/admin/api_players.go | |
| parent | 7eab582d8a8ee2af1a6baae7baf0696c7005de2e (diff) | |
| download | thehouseoficarus-67e01aab85607b9e601185c7d62dff576af3bb43.tar.gz | |
fix: close map OOM, admin traversal, transport safespot, room rekey, and legacy payout recovery
Diffstat (limited to 'internal/admin/api_players.go')
| -rw-r--r-- | internal/admin/api_players.go | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/internal/admin/api_players.go b/internal/admin/api_players.go index 66142c5..8ac0dd2 100644 --- a/internal/admin/api_players.go +++ b/internal/admin/api_players.go @@ -87,7 +87,23 @@ func (s *AdminServer) handlePlayerByID(w http.ResponseWriter, r *http.Request) { } if strings.HasPrefix(path, "account/") { - s.getAccount(w, strings.TrimPrefix(path, "account/")) + acct := strings.TrimPrefix(path, "account/") + if err := player.ValidName(acct); err != nil { + http.Error(w, `{"error":"invalid account id"}`, http.StatusBadRequest) + return + } + s.getAccount(w, acct) + return + } + + // Validate before the first join into players/characters/<name>.yaml. + // ServeMux cleans the ESCAPED path but handlers read the DECODED + // r.URL.Path, so a percent-encoded segment like %2e%2e%2f reaches this + // handler as "../" and would otherwise escape the data dir (and bypass + // the password_hash redaction in getAccount). ValidName is the same + // invariant every other name join in the codebase enforces. + if err := player.ValidName(path); err != nil { + http.Error(w, `{"error":"invalid player id"}`, http.StatusBadRequest) return } |
