Skip to content

fix(security): JS check memory budget, re-authentication for new sign-in factors - #728

Merged
fclairamb merged 15 commits into
mainfrom
security/scan-specs-2026-10-31
Oct 31, 2026
Merged

fclairamb merged 15 commits into
mainfrom
security/scan-specs-2026-10-31

Conversation

@fclairamb

@fclairamb fclairamb commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

What changed

  • AA1 (medium): a JS check now has a 64 MiB per-run memory budget on the native builtins that allocate in one call (repeat, padStart/End, join, Array(n), ArrayBuffer and typed arrays, fill, Array.from, and the length-driven sort, toSorted, map, with, toReversed, toSpliced). A refused call throws a RangeError and the worker keeps running. Spec: specs/done/2026/10/2026-10-31-01-js-checker-memory-budget.md.
  • AA2 (low): turning on TOTP, registering a passkey and setting a first password now need the current password (or, without one, a sign-in within 10 minutes). 2fa/confirm requires a setupToken, and a totp-enabled notice email is sent. dash0 asks for the password first. Spec: specs/done/2026/10/2026-10-31-02-sign-in-factor-enrollment-reauth.md.

Breaking API change: 2fa/setup and passkeys/register/begin refuse a request without currentPassword on accounts with a password; 2fa/confirm needs setupToken. Sessions issued before this have no sign-in time, so passwordless accounts must sign in again once.

Known gaps (not covered): string + doubling, replaceAll, JSON.stringify and TextEncoder can still amplify; the long-term fix is process isolation of check workers (separate spec).

Earlier scan specs (implemented, in specs/done/2026/10/)

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fclairamb and others added 3 commits October 31, 2026 07:28
…in one call

goja checks vm.Interrupt only between instructions, so a single
"x".repeat(1e9) ran to completion whatever the timeout and could OOM-kill
the shared check worker. String.prototype.repeat/padStart/padEnd,
Array.prototype.join (rewritten in Go, charged per piece), the typed-array
join, Array(n), Array.prototype.fill, Array.from, ArrayBuffer and the
typed-array constructors now draw from a 64 MiB per-run budget before they
allocate. A refusal throws a RangeError "memory budget exceeded: ..." and,
uncaught, the check reports error. Pure-JS allocation loops and string
concatenation are still bounded only by the timeout; process isolation is
a separate spec.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ory: the timeout does not stop a native allocation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.76201% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.77%. Comparing base (b2eb48f) to head (58e6b60).

Files with missing lines Patch % Lines
server/internal/checkers/checkjs/memory.go 90.51% 26 Missing ⚠️
server/internal/handlers/auth/factor_reauth.go 89.41% 9 Missing ⚠️
server/internal/handlers/auth/service.go 97.77% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #728      +/-   ##
==========================================
+ Coverage   89.76%   89.77%   +0.01%     
==========================================
  Files        1304     1306       +2     
  Lines      132584   132987     +403     
==========================================
+ Hits       119018   119394     +376     
- Misses      13557    13584      +27     
  Partials        9        9              
Files with missing lines Coverage Δ
server/internal/checkers/checkjs/checker.go 91.83% <100.00%> (+0.01%) ⬆️
server/internal/email/supportreply.go 92.68% <ø> (ø)
server/internal/handlers/auth/email_change.go 89.78% <100.00%> (+0.59%) ⬆️
server/internal/handlers/auth/handler.go 90.57% <100.00%> (+0.14%) ⬆️
server/internal/handlers/auth/join_policy.go 88.08% <100.00%> (ø)
server/internal/handlers/auth/org_profile.go 87.85% <100.00%> (+0.17%) ⬆️
server/internal/handlers/auth/passkey_handler.go 94.69% <100.00%> (+0.35%) ⬆️
server/internal/handlers/auth/passkey_service.go 87.05% <100.00%> (+0.09%) ⬆️
server/internal/handlers/base/base.go 96.49% <ø> (ø)
server/internal/handlers/emailpreview/fixtures.go 100.00% <ø> (ø)
... and 4 more

... and 18 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

fclairamb and others added 11 commits October 31, 2026 07:47
A free length write (a.length = 4e9) made sort/toSorted preallocate
length slots, and map/with/toReversed/toSpliced fill a new array of
that size in one native call. They are now charged 16 bytes per slot
(sort only checked: its buffer is transient). Array-likes are read once
through a length snapshot so a getter cannot answer 0 then 4e9.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ory: the timeout does not stop a native allocation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
POST /auth/2fa/setup and /auth/passkeys/register/begin now need the
current password (or, for an account without one, a sign-in within the
last 10 minutes). /auth/2fa/confirm needs the setupToken returned by
setup. Setting a first password on a passwordless account needs a recent
sign-in. Access tokens carry the primary sign-in time (authTime), copied
through refreshes and org switches. Enabling 2FA sends a totp-enabled
notice email.

New error codes: REAUTHENTICATION_REQUIRED (403), INVALID_SETUP_TOKEN (400).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 2FA setup dialog and the passkey registration ask for the current
password first. An account without a password that has not signed in
within 10 minutes is told to sign in again, also when setting a first
password.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hentication, so a hijacked session can lock out or keep the account

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@fclairamb
fclairamb merged commit a78f954 into main Oct 31, 2026
34 checks passed
@fclairamb
fclairamb deleted the security/scan-specs-2026-10-31 branch October 31, 2026 09:20
fclairamb added a commit that referenced this pull request Oct 31, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.43.0](v0.42.1...v0.43.0)
(2026-10-31)


### Features

* auto-create a personal org for new users, resume OAuth after org
creation ([#716](#716))
([2ae5575](2ae5575))


### Bug Fixes

* **auth:** limit sign-ups per client IP (unconfirmed per day, once a
minute) ([#727](#727))
([b2eb48f](b2eb48f))
* **deps:** update github.com/dop251/goja digest to 032d024
([#724](#724))
([025e97a](025e97a))
* **deps:** update go dependencies (non-major)
([#725](#725))
([5796b1f](5796b1f))
* **deps:** update module github.com/prometheus/common to v0.73.1
([#720](#720))
([9bef875](9bef875))
* **deps:** update module github.com/slack-go/slack to v0.33.0
([#722](#722))
([ad19df4](ad19df4))
* **security:** bug-report budget for non-members, retention sparing
crawl reports
([#715](#715))
([d929999](d929999))
* **security:** JS check memory budget, re-authentication for new
sign-in factors
([#728](#728))
([a78f954](a78f954))


### Performance Improvements

* **dash0:** load only the active language's translations
([#729](#729))
([406f211](406f211))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant