main · last commit
17 hours ago ·
skqvdbd8
sr-ht-compare-11d Give compare's CSRF guard a rendered deny handler instead of nil
Lined Up
bd update sr-ht-compare-11d --claim
bd close sr-ht-compare-11d
| Created by | bigbes |
| Owner | bigbes@gmail.com |
| Created | 2026-08-17T21:37:43Z |
| Updated | 2026-08-17T21:37:43Z |
What is wrong: sourcehut-compare/web/router.go installs 'r.Use(csrf.Require(s.chromeSvc.SelfOrigin(), nil))'. Passing nil selects csrf.denyPlain, a bare text/plain http.Error. Every sibling — sourcehut-{tokens,bench,coverage,curator,specs,artifacts,dolt}/web/router.go — passes a renderer, e.g. 'func(w, r) { s.renderError(w, r, http.StatusForbidden, csrf.Message) }'. Status and message already agree with the siblings; only the presentation differs.
Why it matters: compare has no POST routes today, so nothing is refused yet — but the first form added gets a naked text/plain 403 on a surface whose every other refusal is a rendered page with nav. The router's own comment explains the guard exists 'because the day somebody adds the first POST is exactly the day nobody remembers to add the check'; the same argument applies to the renderer. csrf.Require's doc calls the nil default 'a usable default rather than an invitation to skip the middleware', and compare already has an error renderer (s.renderError) it simply isn't wiring in.
Correct variant: the seven siblings that pass a renderer, e.g. repo/path sourcehut-tokens/web/router.go::csrf.Require call site.
Fix: sourcehut-compare/web/router.go — replace the nil argument with 'func(w, r) { s.renderError(w, r, http.StatusForbidden, csrf.Message) }'.
Note: the register rates this consistency after two source reports disagreed (one called it cosmetic, one correctness-risk); both agree there are currently no POST routes so nothing is refused today.
Audit: D34 (cross-repo audit, 2026-08-17)
No outgoing dependencies.
Nothing depends on this issue.
| id | sr-ht-compare-11d |
| content_hash | d93cb90c612f995ac19f371322ae99fc738ba4348621e8b6f91e81348d776ffa |
| title | Give compare's CSRF guard a rendered deny handler instead of nil |
| description | What is wrong: sourcehut-compare/web/router.go installs 'r.Use(csrf.Require(s.chromeSvc.SelfOrigin(), nil))'. Passing nil selects csrf.denyPlain, a bare text/plain http.Error. Every sibling — sourcehut-{tokens,bench,coverage,curator,specs,artifacts,dolt}/web/router.go — passes a renderer, e.g. 'func(w, r) { s.renderError(w, r, http.StatusForbidden, csrf.Message) }'. Status and message already agree with the siblings; only the presentation differs. Why it matters: compare has no POST routes today, so nothing is refused yet — but the first form added gets a naked text/plain 403 on a surface whose every other refusal is a rendered page with nav. The router's own comment explains the guard exists 'because the day somebody adds the first POST is exactly the day nobody remembers to add the check'; the same argument applies to the renderer. csrf.Require's doc calls the nil default 'a usable default rather than an invitation to skip the middleware', and compare already has an error renderer (s.renderError) it simply isn't wiring in. Correct variant: the seven siblings that pass a renderer, e.g. repo/path sourcehut-tokens/web/router.go::csrf.Require call site. Fix: sourcehut-compare/web/router.go — replace the nil argument with 'func(w, r) { s.renderError(w, r, http.StatusForbidden, csrf.Message) }'. Note: the register rates this consistency after two source reports disagreed (one called it cosmetic, one correctness-risk); both agree there are currently no POST routes so nothing is refused today. Audit: D34 (cross-repo audit, 2026-08-17) |
| design | |
| acceptance_criteria | |
| notes | |
| status | open |
| priority | 3 |
| issue_type | chore |
| assignee | NULL |
| estimated_minutes | NULL |
| created_at | 2026-08-17T21:37:43Z |
| created_by | bigbes |
| owner | bigbes@gmail.com |
| updated_at | 2026-08-17T21:37:43Z |
| closed_at | NULL |
| closed_by_session | |
| external_ref | NULL |
| spec_id | |
| compaction_level | 0 |
| compacted_at | NULL |
| compacted_at_commit | NULL |
| original_size | NULL |
| sender | |
| ephemeral | 0 |
| wisp_type | |
| pinned | 0 |
| is_template | 0 |
| mol_type | |
| work_type | |
| source_system | |
| metadata | �{} |
| source_repo | |
| close_reason | |
| event_kind | |
| actor | |
| target | |
| payload | |
| await_type | |
| await_id | |
| timeout_ns | 0 |
| waiters | |
| hook_bead | |
| role_bead | |
| agent_state | |
| last_activity | NULL |
| role_type | |
| rig | |
| due_at | NULL |
| defer_until | NULL |
| no_history | 0 |
| started_at | NULL |
| is_blocked | 0 |
| id | 01a011a8-b004-7f3a-ae62-3eaec3004a8e |
| issue_id | sr-ht-compare-11d |
| event_type | created |
| actor | bigbes |
| old_value | |
| new_value | |
| comment | NULL |
| created_at | 2026-08-18T00:37:42Z |
No comments.