GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Tags · bQuery/bQuery

Tags

v1.18.0

Toggle v1.18.0's commit message
release: 1.18.0 (#279)

  • Oct 23, 2026
  • 0a87a76
  • zip
  • tar.gz
  • Notes

v1.17.2

Toggle v1.17.2's commit message
release: 1.17.2 (#275)

## Summary

- Release PR for **1.17.2**: a security patch that closes cookie tossing
for the CSRF and session cookies.
- `csrf()` and `session()` name their cookies `__Host-bq.csrf` and
`__Host-bq.sid` by default. A sibling subdomain or a network attacker
can therefore no longer plant or overwrite them (#274, `3ecaa91`).
- No API removals and no module status transitions. The two behaviour
changes are listed under **Notes for reviewers**. The session one **logs
users out once**.
- All guides are brought up to date for 1.17.x (`ea9938c`, `a360e96`).

## Motivation

- 1.17.1 keeps the CSRF secret in the session for visitors who have one.
Forms rendered without a session, such as the login form, still relied
on a plantable `bq.csrf` cookie. This was the last open item of the
private advisory on signed CSRF tokens.
- The code review on this PR found that the session cookie `bq.sid` was
open to the same attack. A subdomain could plant a validly signed id for
the attacker's own session. The victim's requests then ran in the
attacker's account (session swapping), and the attacker knew the
matching CSRF token.

## Changes included

The diff against `main` is **27 files, +340/−56**:

- **#274** (`src/server/csrf.ts`, tests, server guide):
- The CSRF cookie defaults to `__Host-bq.csrf` when `secure: true`,
`path: '/'` and no `domain`; otherwise it is `bq.csrf`.
  - The server guide documents the limitation of unsigned mode.
- **Release commit (`8a4fc05`)**:
  - `package.json` → `1.17.2`.
  - AI guidance files synced (`check:ai-guidance` passes).
  - CHANGELOG entry, `docs/release-notes/1.17.2.md`, index and sidebar.
- **Review fixes (`3ecaa91`)**:
- `session()` defaults to `__Host-bq.sid` under the same rule, with
`bq.sid` as the fallback.
- `csrf()` and `session()` throw at startup when a `cookieName` carries
a `__Host-` or `__Secure-` prefix its attributes violate. Prefixes are
matched case-insensitively, as browsers do. `SameSite=None` counts as
`Secure`.
- The shared rule lives in `src/server/cookies.ts`, internal and not
exported.
- Tests cover these cases, and the cross-runtime smoke test expects the
new session cookie name.
- **Docs refresh (`ea9938c`, `a360e96`)**:
  - **Server guide:**
- `ctx.html()` sanitizes without a DOM since 1.17.0, so the old
`happy-dom` shim instructions are removed.
- The opt-out is `{ trusted: true }`; the guide wrongly said `{
sanitize: false }`.
    - `secure: true` is already the session default.
- A pitfall now covers the `__Host-` names, and the version history
covers 1.17.0–1.17.2.
- **Version histories** in the core, reactive, router, forms, store,
component, view, security and ssr guides now cover 1.17.0 and 1.17.1.
- **SSR docs and `llms.txt`:** the CI matrix runs the latest Bun
(`llms.txt` still said Bun 1.3). Bun ≥ 1.4.0 stays the documented
support floor.
- **Trusted Types notes** state that a `trusted-types` directive must
allow the `bquery-sanitizer` policy.

`SECURITY.md` already lists `1.17.x` as supported.

## Validation

- [x] `bun run format:check`, `bunx eslint .`, `bun run lint:types`,
`bun run test:types`
- [x] `bun run check` (incl. `check:ai-guidance` → 1.17.2)
- [x] `bun run build`, `check:publish`, `check:size`, `check:package`
- [x] `bun test`: 3574 pass, 0 fail
- [x] `bun run test:coverage`, run twice
- [x] `bun run docs:build`: no dead links
- [x] `tests/cross-runtime/run.mjs` on Bun and Node: 16/16
- [x] Without the `3ecaa91` source changes, 12 tests fail, including
every new one.
- [x] GitHub CI green on every head, the latest being `a360e96` (27/27).

## Checklist

- [x] I followed the contributing guidelines.
- [x] I added or updated tests where behavior changed.
- [x] I updated documentation when public behavior or developer workflow
changed.
- [x] I confirmed the change does not introduce security-sensitive
regressions.

## Notes for reviewers

- **Behaviour change: CSRF cookie name.** With the default attributes
the cookie is `__Host-bq.csrf` instead of `bq.csrf`.
  - A form rendered before the upgrade fails once with `403`.
- Client code that reads the cookie directly must use the new name or
pass `cookieName: 'bq.csrf'`.
- **Behaviour change: session cookie name, one-time logout.** With the
default attributes the cookie is `__Host-bq.sid` instead of `bq.sid`.
  - Existing sessions are not read any more.
- The old name is deliberately not accepted as a fallback, because that
would reopen session swapping.
- `cookieName: 'bq.sid'` keeps existing sessions for a transition
period.
- **Prefixed names** that the browser would drop now throw at startup.
Such cookies never worked in browsers.
- **Review status:** every review thread is resolved. CodeRabbit
confirmed the fixes in `a360e96`.
- **After merging:**
  - Tag `v1.17.2` and publish.
  - Merge `main` back into `dev` with a merge commit, not a squash.
- Consider publishing the GitHub Security Advisories for ≤ 1.17.1 (CSRF
and session cookie tossing) and for ≤ 1.17.0 (#269–#271).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01MdbZH1BQLrEGMoMD3gdBBo

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Security**
* Default CSRF and session cookies now use the `__Host-` prefix when
cookie settings meet its requirements; otherwise, the unprefixed names
remain in use.
* Invalid combinations of prefixed cookie names and settings now produce
startup errors.
* Existing sessions are no longer recognized, so users may need to sign
in again. Older CSRF forms may fail once with a 403, and client code
that accesses the CSRF cookie may need updating.
* **Documentation**
* Updated guides and release notes with cookie compatibility details and
version 1.17.2.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5 <[email protected]>
  • Oct 1, 2026
  • acb0eb8
  • zip
  • tar.gz
  • Notes

v1.17.1

Toggle v1.17.1's commit message
release: 1.17.1 (#272)

## Summary

- Release PR for **1.17.1**. It brings everything on `dev` since
`1.17.0` into `main`.
- Security-and-correctness patch closing the 1.17.0 audit:
  - three security fixes in `server` and `ssr`;
- ten bug fixes across `core`, `router`, `server`, `reactive`, `forms`,
`store`, `component` and `view`.
- No API removals and no module status transitions. A few behaviour
changes are listed under **Notes for reviewers**.

## Motivation

`dev` is 13 PR merges ahead of `main` (#259–#271). Together they close
issues #246–#253, #256 and #258 (all closed) and the three privately
reported vulnerabilities fixed in #269, #270 and #271.

## Changes included

This PR targets `main`, so the diff shows the whole `1.17.0 → 1.17.1`
delta: **48 files, +2007/−100**. It has three commits on top of `dev`.

**Release commit (`d9d20de`)** contains only metadata and documentation:

- **Version:** `package.json` → `1.17.1`. `AGENT.md`, `llms.txt`,
`.github/copilot-instructions.md`, `.cursorrules` and `.clinerules` are
synced; `check:ai-guidance` passes. `SECURITY.md` already lists
`1.17.x`.
- **Changelog:** `CHANGELOG.md` gets a `[1.17.1] - 2026-09-28` entry
with Security / Fixed / Changed sections.
- **Release notes:** new `docs/release-notes/1.17.1.md`, plus a row in
the release-notes index.
- **Pre-existing doc fixes:**
  - The 1.17.0 release notes page was missing from the sidebar.
- Its date and CHANGELOG anchor said `2026-09-21`; the release date is
`2026-09-25`, so the anchor pointed nowhere.
- **Guides aligned with shipped behaviour:**
- `api-core.md` describes `show()`/`hide()`/`toggle()` and camelCase
`css()` as they work after #262/#263.
  - `router.md` documents decoded params (#260).

**Review-fix commits (`61198bc`, `640830a`)** address the findings from
the review on this PR:

- **Session-bound CSRF (#271):**
- Requests without a stored session use the signed CSRF cookie and never
write to the session. Anonymous traffic can no longer fill the capped
session store or evict real sessions from it.
- A session created during such a request adopts the cookie secret, so
forms rendered earlier still verify.
- A session created or regenerated with `$regenerate()` (a login) always
gets a fresh secret, so a planted cookie cannot reach the authenticated
session.
  - A session removed with `$destroy()` is not written back.
- For a stored session the secret is bound before `next()`, so a token
read later from a streamed body or `ctx.sse()` stays valid.
- **`toggle()` (#263):** `hidden="until-found"` counts as hidden even
with an inline `display`, because it hides through `content-visibility`.
The `api-core.md` list entry now names the inline-`display` exception.

Source changes by PR:

| PR | Change |
| --- | --- |
| #269 | Security: `serveStatic` `realpath` containment for
precompressed sidecars |
| #270 | Security: Node adapter answers handler errors with `500`
instead of crashing; cancels streams and aborts `request.signal` on
disconnect |
| #271 | Security: signed CSRF tokens bound to the session and rotated
on `$regenerate()` (refined in `61198bc`/`640830a`) |
| #259 | `deepEqual`/`isEqual` kind mismatches (#246) |
| #260 | Router: decoded params, encoded static segments (#247) |
| #261 | Server: encoded static route segments (#248) |
| #262 | `css()` camelCase (#249) |
| #263 | `toggle()`/`hide()`/`show()` (#250) |
| #264 | Already-aborted `AbortSignal` in `http` and `listen()` (#251) |
| #265 | Linear-time `email()` (#252) |
| #266 | Trusted Types for component render, `createTemplate()` and the
DOM sanitizer (#253) |
| #267 | `memoryStore()` sweeping, LRU eviction, default cap (#256) |
| #268 | `SECURITY.md` supported line and drift check (#258) |

## Validation

- [x] `bunx eslint .` + `bun run format:check`
- [x] `bun run build`, `check:publish`, `check:size`, `check:package`
- [x] `bun test`: 3568 pass, 0 fail; `test:types` and `lint:types` clean
- [x] `bun run test:coverage` (coverage floor), `bun run check` (incl.
`check:ai-guidance` → 1.17.1) and `bun run docs:build` (no dead links)
- [x] Each regression test added in the review-fix commits fails without
its fix.

## Checklist

- [x] I followed the contributing guidelines.
- [x] I added or updated tests where behavior changed. They were added
in the individual fix PRs and in the review-fix commits.
- [x] I updated documentation when public behavior or developer workflow
changed.
- [x] I confirmed the change does not introduce security-sensitive
regressions.

## Notes for reviewers

**Behaviour changes when upgrading** (also in the CHANGELOG and release
notes):

- **Router params are decoded.** Remove any manual
`decodeURIComponent()`.
- **CSRF with `session()` before `csrf({ secret })`:**
- requests with a stored session get no `bq.csrf` cookie; the secret
lives in the session;
  - visitors without a session keep the signed `bq.csrf` cookie;
- the token rotates on `$regenerate()`, so render a fresh
`csrfToken(ctx)` after login;
  - `bindToSession: false` opts out.
- **`listen({ signal })`** rejects when the signal is aborted before or
during binding.
- **The default session store** evicts beyond 10 000 live sessions.
- **`show()` without an argument** keeps the inline `display` of an
element that is not inline-hidden.
- **`email()`** rejects empty domain labels and addresses over 254
characters.

**Known limitation:** forms rendered to visitors without a session (for
example the login form) rely on the signed cookie, as before 1.17.1. The
server guide recommends a `__Host-` cookie name for that case.

**After merging:** tag `v1.17.1`, publish, and merge `main` back into
`dev`, as after 1.17.0. The review-fix commits exist only on this
branch, so that merge back is required. Consider publishing a GitHub
Security Advisory for ≤ 1.17.0 that covers #269–#271.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01MdbZH1BQLrEGMoMD3gdBBo

---
_Generated by [Claude
Code](https://claude.ai/code/session_01MdbZH1BQLrEGMoMD3gdBBo)_

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved protection against static-file sidecar paths escaping the
configured root and strengthened CSRF protection for session-backed
requests.
* Node server handlers now handle errors and client disconnects more
safely; server startup also responds correctly to cancelled requests.
* Fixed URL-encoded route matching, CSS property handling, visibility
toggling, equality checks, HTTP cancellation, and email validation.
* Expired sessions are cleaned up, and the default in-memory session
store now limits its capacity.

* **Documentation**
* Added version 1.17.1 release notes and updated security guidance and
feature documentation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5 <[email protected]>
  • Sep 30, 2026
  • 2d48260
  • zip
  • tar.gz
  • Notes

v1.17.0

Toggle v1.17.0's commit message
Change release date for version 1.17.0 to 2026-09-25

Updated release date for version 1.17.0 and modified upgrade instructions.

Signed-off-by: Jonas Pfalzgraf <[email protected]>
  • Sep 24, 2026
  • 385f0e5
  • zip
  • tar.gz
  • Notes

v1.16.1

Toggle v1.16.1's commit message
chore: release 1.16.1 - update Bun version to 1.4.0, refresh dev depe…

…ndencies, and fix Vite build warnings (#206)
  • Aug 26, 2026
  • b1c4c66
  • zip
  • tar.gz
  • Notes

v1.16.0

Toggle v1.16.0's commit message
Release 1.16.0 — quality & performance pass (#203)

  • Aug 11, 2026
  • 6eb76be
  • zip
  • tar.gz
  • Notes

v1.15.1

Toggle v1.15.1's commit message
Release 1.15.1 — security & correctness patch (#202)

# Release 1.15.1 — Security & correctness patch

Promotes `dev` to `main` for the **1.15.1** patch release. This closes
the findings of a full-codebase security & correctness audit (issues
[#162](https://github.com/bQuery/bQuery/issues/162)–[#181](https://github.com/bQuery/bQuery/issues/181)).

**No breaking changes. No module status transitions.** Every 1.15.0 and
earlier API continues to work unchanged — upgrading is a drop-in.

## Security fixes

| Area | Fix | Issue |
| --- | --- | --- |
| security | mXSS-detection fallback in `sanitizeHtml` now HTML-escapes
its text result (reachable through every HTML sink) |
[#162](#162) |
| ssr | `bq-text` on raw-text elements (`textarea`/`title`) escaped in
the pure renderer (stored XSS) |
[#163](#163) |
| view/ssr | `bq-bind` guards `on*`/URL/`srcset`/`srcdoc` values via a
shared bind-guard | [#164](#164)
|
| view | `with`-scoped evaluator shadows dangerous globals — closes
`constructor.constructor(…)()` RCE |
[#168](#168) |
| ssr | DOM-backed evaluator routed through the CSP-safe parser (removes
`new Function()`) | [#167](#167)
|
| server | session + CSRF cookies default to `Secure` |
[#169](#169) |
| security | Trusted Types wired into HTML sinks (new
`trustedHtmlForSink()`) |
[#171](#171) |
| ssr | `bq-style` declarations validated (CSS injection) |
[#176](#176) |
| security | expanded DOM-clobbering denylist + duplicate-id stripping |
[#179](#179) |
| i18n | own-property checks for placeholder/key resolution |
[#174](#174) |
| store | `deepClone` guards `__proto__` |
[#175](#175) |
| server | file-route loaders default to the action middleware chain
(authz) | [#181](#181) |

## Correctness fixes

| Area | Fix | Issue |
| --- | --- | --- |
| store | `$subscribe` snapshots subscribers (no skip on
unsubscribe-during-notify) |
[#165](#165) |
| reactive | self-triggering effects bounded instead of overflowing the
stack | [#166](#166) |
| view/compiler | bail on unterminated string / invalid numeric literals
| [#170](#170) |
| reactive | overlapping `useFetch`/`useAsyncData` abort the superseded
request | [#172](#172) |
| reactive/concurrency | disposal paths for `deferred()` /
`persistedSignal()` (+ `effectScope(detached)`) |
[#173](#173) |
| ssr | `titleTemplate` inserts the title literally (no `$&` mangling) |
[#177](#177) |
| core | `debounce({leading,trailing})` no longer double-invokes a
single call | [#178](#178) |
| view | `bq-on` invokes handlers via evaluation, not a paren heuristic
| [#180](#180) |

## Additive APIs (backwards-compatible)

- `trustedHtmlForSink()` — `@bquery/bquery/security` (also on `/full`)
- `effectScope(detached?)` — `@bquery/bquery/reactive`
- `deferred()` handle now exposes `dispose()`

## Migration notes

Two behavioural defaults tightened, both with explicit opt-outs:

- Server session/CSRF cookies now set `Secure` → pass `cookie: { secure:
false }` for local HTTP dev.
- File-route JSON loaders now inherit `middlewares` → pass
`dataMiddlewares: []` to keep them unauthenticated.

## Release chores

- `package.json`: 1.15.0 → 1.15.1
- `CHANGELOG.md`: new `[1.15.1]` section (Security + Fixed) and TOC
entry
- Docs: new `release-notes/1.15.1` page, nav + index entries,
`trustedHtmlForSink()` documented in the Security guide

## Validation

- `bun test`: 3043 pass / 0 fail
- `tsc --noEmit` (src + tests): clean
- `bun run build`: succeeds
- `check:stability`, `check:doc-exports` (security 11/11),
`check:full-bundle`: pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Security**
* Hardened HTML/SSR rendering and `bq-bind`/`bq-html`/`bq-text` handling
against XSS, dangerous URL protocols, DOM clobbering, and
prototype-chain attacks.
* Added/strengthened Trusted Types protections and SSR CSP-safe
evaluation behavior.
* Updated secure-by-default cookie settings (session + CSRF) and
improved authorization middleware inheritance for generated JSON loader
routes.
* **Bug Fixes**
* Fixed store subscriber notification stability, bounded reactive cyclic
re-runs, deferred cleanup/disposal behavior, and overlapping `useFetch`
aborting.
* Corrected `debounce` leading+trailing behavior and various
SSR/template and i18n edge cases.
* **New Features**
* Added `trustedHtmlForSink` helper for Trusted Types HTML sink
assignments.
* Added `effectScope(detached)` with manual stopping and enhanced
`deferred()` to support explicit disposal.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Jonas Pfalzgraf <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
  • Jul 6, 2026
  • d6b8e30
  • zip
  • tar.gz
  • Notes

v1.15.0

Toggle v1.15.0's commit message
Update release date for version 1.15.0

Signed-off-by: Jonas Pfalzgraf <[email protected]>
  • Jun 30, 2026
  • b43c847
  • zip
  • tar.gz
  • Notes

v1.14.2

Toggle v1.14.2's commit message
chore: update actions/checkout and bun setup versions across workflows

  • Jun 26, 2026
  • d26b720
  • zip
  • tar.gz
  • Notes

v1.14.1

Toggle v1.14.1's commit message
Enhance concurrency, SSR, server runtime, and documentation updates (#…

…118)
  • May 28, 2026
  • 15d301d
  • zip
  • tar.gz
  • Notes
PreviousNext
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.