aboutsummaryrefslogtreecommitdiffstats
path: root/internal
diff options
context:
space:
mode:
authorgrm <grm@eyesin.space>2026-09-18 13:49:53 +0300
committergrm <grm@eyesin.space>2026-09-18 13:49:53 +0300
commitc47397ac1e2ceafafe2be3cdec86366dd396ed6f (patch)
tree72474c50ed5ffc75595445bef72ac6c340922cc1 /internal
parentd23fe805546e992c8033d64d7177fe1454ad7716 (diff)
downloadblogspace-c47397ac1e2ceafafe2be3cdec86366dd396ed6f.tar.gz
blogspace-c47397ac1e2ceafafe2be3cdec86366dd396ed6f.tar.bz2
blogspace-c47397ac1e2ceafafe2be3cdec86366dd396ed6f.zip
Security: Clamp page numbers so a huge ?p= cannot overflow the offset
?p=9223372036854775807 made (n-1)*per wrap negative, Postgres refused the OFFSET and every listing, tag and search page answered 500 — a line in the log per request for any bot fuzzing query strings. Page numbers now stop at 100000. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal')
-rw-r--r--internal/web/handlers_blog.go10
-rw-r--r--internal/web/web_test.go8
2 files changed, 14 insertions, 4 deletions
diff --git a/internal/web/handlers_blog.go b/internal/web/handlers_blog.go
index d9caf22..f138c58 100644
--- a/internal/web/handlers_blog.go
+++ b/internal/web/handlers_blog.go
@@ -67,13 +67,15 @@ func (s *Server) blogView(r *http.Request) (map[string]any, error) {
// (typed, so the layout's index lookups still work).
var noNotices = map[string][]Notice{}
+// maxPageNum bounds ?p=: no listing is that long, and (n-1)*per must not
+// overflow into a negative OFFSET, which Postgres refuses (a 500 for a bot to
+// trigger at will).
+const maxPageNum = 100000
+
// pageNum reads the ?p= of a paginated listing (1 when absent or silly).
func pageNum(r *http.Request) int {
n, _ := strconv.Atoi(r.URL.Query().Get("p"))
- if n < 1 {
- n = 1
- }
- return n
+ return min(max(n, 1), maxPageNum)
}
func (s *Server) handleBlogHome(w http.ResponseWriter, r *http.Request) {
diff --git a/internal/web/web_test.go b/internal/web/web_test.go
index dfc9629..2f3bc4f 100644
--- a/internal/web/web_test.go
+++ b/internal/web/web_test.go
@@ -1080,3 +1080,11 @@ func TestSecurityHeaders(t *testing.T) {
}
}
}
+
+func TestPageNum(t *testing.T) {
+ for in, want := range map[string]int{"": 1, "0": 1, "-3": 1, "x": 1, "7": 7, "9223372036854775807": maxPageNum} {
+ if got := pageNum(httptest.NewRequest("GET", "/?p="+in, nil)); got != want {
+ t.Errorf("p=%q: %d, want %d", in, got, want)
+ }
+ }
+}