aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/api_players.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-18 15:42:23 -0400
committerhistoria <[not public]>2026-09-18 15:42:23 -0400
commit67e01aab85607b9e601185c7d62dff576af3bb43 (patch)
tree059134b2434eba7c14aa9d89f48c5a475feb0312 /internal/admin/api_players.go
parent7eab582d8a8ee2af1a6baae7baf0696c7005de2e (diff)
downloadthehouseoficarus-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.go18
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
}