diff options
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 } |
