mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-07-04 17:11:37 +00:00
7421ead9b0
This PR replaces the strict, hardcoded limits on API list endpoints (introduced in the recent security patch) with a new operator-configurable `listLimits` block. This change is needed as issue 1540's implementation introduced a 500max node limit on the live map or any other function that leverages the api/nodes backend. Previously, we attempted to bypass public caps for internal UI requests using a heuristic based on browser headers (`Sec-Fetch-Site`). Following review, we decided to drop that heuristic entirely to eliminate any security-by-browser-convention surface area. Instead, `queryLimit()` returns to its original, mathematically simple bounds-checking shape, and the absolute maximums are now drawn from `config.json`. This provides equal DoS protection against all callers while allowing server operators to tune the ceilings based on the size of their mesh (e.g. embedded devices can tighten the knobs, regional hubs can raise them). ### Changes Made: - **`config.go`**: Introduced a `ListLimits` config struct containing `PacketsMax`, `NodesMax`, `AnalyticsMax`, and `ChannelMessagesMax`. Added safe initialization to ensure default caps (10000, 2000, 200, 500 respectively) apply even if the block is omitted from the config. - **`clamp_limit.go`**: Deleted `isInternalUIRequest` entirely and restored `queryLimit` to its original signature (`r, def, max`). - **`routes.go`**: Replaced all hardcoded integer ceilings on list endpoints (`/api/packets`, `/api/nodes`, etc.) with `s.cfg.ListLimits.*`. - **`config.example.json`**: Added the `listLimits` block with documentation to guide new operators. - **`clamp_limit_test.go`**: Purged all header-heuristic testing. ### Verification: - All 611 backend unit tests pass (`npm run test:unit`). - Bounds-checking math continues to enforce hard DoS clipping exactly at the operator's specified configuration limit. --------- Co-authored-by: mc-bot <bot@openclaw.local> Co-authored-by: openclaw-bot <bot@openclaw>
36 lines
1.0 KiB
Go
36 lines
1.0 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
)
|
|
|
|
// clampLimit parses a `limit`-shaped string and clamps it into [1, max].
|
|
// Empty / non-numeric / zero / negative inputs return def.
|
|
// Values exceeding max are clamped to max.
|
|
//
|
|
// This is the uniform helper for list-endpoint `limit` parameters; prefer it
|
|
// over inline `if limit > N { limit = N }` patterns so the absolute caps stay
|
|
// consistent across handlers. See audit-input-vulns-20260603 (MEDIUM —
|
|
// unbounded `limit` on list endpoints).
|
|
func clampLimit(raw string, def, max int) int {
|
|
if raw == "" {
|
|
return def
|
|
}
|
|
n, err := strconv.Atoi(raw)
|
|
if err != nil || n <= 0 {
|
|
return def
|
|
}
|
|
if n > max {
|
|
return max
|
|
}
|
|
return n
|
|
}
|
|
|
|
// queryLimit reads the `limit` query parameter from r and clamps it through
|
|
// clampLimit. Convenience wrapper used by HTTP handlers so existing
|
|
// queryInt(r, "limit", def) call sites can become queryLimit(r, def, max).
|
|
func queryLimit(r *http.Request, def, max int) int {
|
|
return clampLimit(r.URL.Query().Get("limit"), def, max)
|
|
}
|