Skip to content

Admit only plausible board times, and print any time without throwing (F07) - #9

Merged
sol-znn merged 2 commits into
sol-znn:092026-auditfrom
0x3639:fix/f07-plausible-board-times
Sep 13, 2026
Merged

sol-znn merged 2 commits into
sol-znn:092026-auditfrom
0x3639:fix/f07-plausible-board-times

Conversation

@0x3639

@0x3639 0x3639 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

The finding

F07 (Low / P3) from the Codex Security audit of be879e1: A crafted take timestamp disables the shared board inbox. A take is stamped by whoever signs it, a relay this browser was pointed at delivers whatever a key will sign, and the inbox formatted every take's stamp with toISOString() inside one shared render. A stamp Go's int64 holds happily but a JavaScript Date does not threw there, and the throw took every legitimate take down with the bad one, their Accept and Dismiss controls included.

The fix

Two changes, one at each end.

  • At the read boundary, OpenTake refuses a stamp outside a window nothing real falls outside of, before 2020, after 2100, or more than a day ahead of this reader's clock, before the box is opened. A post's own creation and expiry times are held to the same window when the post is validated. The supported post TTL is ten minutes to seven days, so the ceiling constrains nothing real.
  • On the page, the board's dates go through a total formatter: a time a Date can hold prints as before, and anything else prints a dash, never a throw. The inbox and both post rows use it, so the engine's refusal is not the only thing between a stamp and a blank inbox.

Tests

  • Go: a take re-stamped and re-signed beyond what a Date can hold, in the far future, before the board existed, negative, or two days ahead is refused, while now and a day ahead (a wrong clock) are opened; the window's exact edges and the future bound five seconds either side; a post expiring beyond any Date or created before the board is refused.
  • Node (npm run dates, new, in CI and npm test): the formatter does not throw and prints a dash for a value beyond a Date, a hugely negative one, NaN, infinity, undefined and a string, and formats an ordinary time correctly.
  • go test ./..., typecheck, lint, build and the 145-check smoke run pass.

Review trail

One Codex Security review on Daybreak at High: APPROVE WITH NITS, verify-fix "fixed". It also traced the post and presence-beat timestamp paths and found no other relay-delivered time reaching a throwing Date operation. Its boundary-value nit is in the second commit; its request for a component-level mixed-inbox test is left open, as this repository has no component test harness.

Branched from and targeting 092026-audit. This is the last of the seven findings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UYCAfS9BXS9N9eCe39BRCg

0x3639 and others added 2 commits September 12, 2026 04:06
… (F07)

Audit finding F07 (Low): a take is stamped by whoever signs it, a relay
this browser was pointed at delivers whatever a key will sign, and the
inbox formatted every take's stamp with toISOString() inside one shared
render. A stamp Go's int64 holds happily but a JavaScript Date does not
threw there, and the throw took every legitimate take down with the bad
one -- their Accept and Dismiss controls included.

Two changes, one at each end. At the read boundary, OpenTake refuses a
stamp outside a window nothing real falls outside of -- before 2020, after
2100, or more than a day ahead of this reader's clock -- before the box is
opened; a post's own creation and expiry times are held to the same
window when the post is validated. On the page, the board's dates go
through a total formatter: a time a Date can hold prints as before, and
anything else prints a dash, never a throw. The inbox and both post rows
use it, so Go's refusal is not the only thing between a stamp and a
blank inbox.

Tests: a take re-stamped and re-signed beyond what a Date can hold, in the
far future, before the board existed, negative, or two days ahead is
refused, while now and a day ahead (a wrong clock) are opened; a post
expiring beyond any Date or created before the board is refused. A new
Node check (npm run dates, in CI and npm test) pins that the formatter
does not throw and prints a dash for a value beyond a Date, a hugely
negative one, NaN, infinity, undefined and a string, and formats an
ordinary time correctly.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYCAfS9BXS9N9eCe39BRCg
Nit from the approving review: the floor and ceiling are admitted, one
second beyond either is not, and the take's future bound is tested five
seconds inside and five seconds beyond.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYCAfS9BXS9N9eCe39BRCg
@sol-znn
sol-znn merged commit 028c03d into sol-znn:092026-audit Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants