The cookie approach seems like the more secure aproach because it ties the authentication or registration attempt to the user's browser session, but it doesn't work reliably on Chrome for Windows. Also, a simila problem pops up on Chrome for Linux if the session is used instead of a separate cookie. It looks like the browser doesn't propagate the state change through fast enough which results in some requests contaiining the new/updated cookie, and others don't, which results in sporadic failures. Since we use a signed and expiring challange we still get protection from replay attacks and tampering which enables us to omit the cookie entierly and rely on the challange's signature to prove expiration and authenticity. The only thing we lose is the ability to tie and attemp to a single browser session.
See: https://github.com/w3c/webauthn/wiki/Explainer:-WebAuthn-challengeURL which proposes to add the same challange fetching logic as part of the standard
See: https://github.com/w3c/webauthn/issues/1856 which discusses issues that arise from having expiring challanges (which the spec recommends)
See: https://github.com/OneUptime/oneuptime/security/advisories/GHSA-gjjc-pcwp-c74m which is an explot that can happen if the server isn't able to verify the authenticity of challanges that are sent outside of a cookie
This simplifies the loading and cleanup logic, while providing ubiquitous support across JS frameworks. Buttons can now be added in any way imaginable and still work without requiring additional initialization. The upside of this aproach is that it doesn't require a mutation observer nor a global click listener, and is supported by all browsers that also support passkeys.
This is a guess based on a few articles I read where Windows Hello doesn't play nice with Same-Site: Strict. I have no credible evidence to back this up.
No longer needed since the scrubber is not memoized across calls and the
text node length guard prevents the performance issue.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A large comment body was causing Regexp::TimeoutError in production.
The URI regexp isn't catastrophically backtracking — it's linear — but
with a long enough string it exceeds the 1s Regexp.timeout set by
Rails.
Skip scanning text nodes over 10KB, which is well beyond any
reasonable content for auto-linking and still keeps us many orders of
magnitued under the timeout on an unloaded machine.
Fixes FIZZY-Q4
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The scrubber was memoized on the view helper in b0fa6525 so that
@regexp_timeout_reported would stop scanning remaining text nodes
after a timeout. But memoizing on the helper leaks that flag across
all format_html calls for the entire request — if one comment triggers
a timeout, every subsequent comment on the page loses auto-linking.
Use a fresh scrubber per call. The @regexp_timeout_reported flag still
works within a single document's scrub, which is the intended scope.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three changes needed to support navigating back from a card to the
activity page:
- Add root_path to the prefer_referrer allowlist on the card show page
- Switch event links from HTML target="_top" to data-turbo-frame="_top"
so Turbo handles the navigation and turbo:before-visit fires to save
the referrer
- Normalize trailing slashes in the referrer path comparison so
/account_id and /account_id/ both match
ref: https://app.fizzy.do/5986089/cards/2390