Skip to content

fix(security): audit fixes — storage masking defaults, page-bridge target origin, CI permissions#362

Merged
vamgan merged 2 commits into
mainfrom
claude/security-audit-fixes
Jul 2, 2026
Merged

fix(security): audit fixes — storage masking defaults, page-bridge target origin, CI permissions#362
vamgan merged 2 commits into
mainfrom
claude/security-audit-fixes

Conversation

@vamgan

@vamgan vamgan commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Full-repo security + bloat audit. Three confirmed issues fixed, one bloat cleanup, and a clean bill of health on the rest (details below).

Fixes

1. Storage source captured secrets by default (privacy, medium-high)

createAskableStorageSource() with no options captured every localStorage key verbatim — auth tokens, JWTs, session ids — straight into AI context / MCP responses. New maskSensitiveKeys option (default true) masks values whose keys match token/secret/password/auth/jwt/api-key/credential/session-id/cookie/private, composing with the existing maskKeys. Opt out with maskSensitiveKeys: false. 4 new tests (incl. masking even for explicitly-listed keys).

2. Page bridge could post packets with targetOrigin: '*' (medium)

resolveAskableMcpPageBridgeTargetOrigin fell back to '*' when event.origin was empty — the classic postMessage broadcast leak for exactly the data this library exists to protect. Now falls back to the bridge window's own origin and drops the response entirely when no origin is known. Regression test added.

3. Three CI workflows ran with default token permissions (low)

test_unit.yml, test_e2e.yml, static_quality.yml had no permissions: block. Added least-privilege contents: read (matching the already-hardened publish workflows).

4. Bloat: 364 KB of unreferenced duplicate assets

examples/analytics-dashboard-react/public/icon-{light,dark}-32x32.png were byte-identical 182 KB copies of avatar.png (not actually 32×32), referenced nowhere. Deleted.

Audited and clean (no action needed)

  • XSS/injection: zero innerHTML/insertAdjacentHTML/document.write/eval/new Function/dangerouslySetInnerHTML in any package source; capture/selection/inspector overlays build DOM exclusively via createElement + textContent; React/Solid inspectors render via JSX/text.
  • Prototype pollution: data-askable JSON is spread shallowly, never deep-merged.
  • Workflows: all github.event.* interpolation goes through env: indirection (no script injection); publish uses OIDC provenance with minimal permissions; no pull_request_target.
  • Dependencies: npm audit --omit=dev0 vulnerabilities.
  • Repo hygiene: no committed node_modules/.DS_Store/build artifacts; docs pages all reachable from the sidebar; no unused package dependencies found; create-app templates carry no lockfiles.

Notes (flagged, deliberately not changed)

  • site/www/askable-ui-code.mp4 (6.5 MB) is the largest blob in git — it's the in-use product video; consider hosting via release assets/CDN if repo size becomes a concern.
  • The web handler's Content-Length-based body limit can't see chunked bodies; the MCP SDK transport sits behind it. Hardening candidate, not a confirmed vulnerability.

Test plan

  • core 531/531 (5 tests added/updated) · mcp 51/51 (1 added)
  • full workspace build clean
  • CI green

🤖 Generated with Claude Code


Generated by Claude Code

claude added 2 commits July 2, 2026 01:01
…gin, CI permissions

Security audit fixes:
- storage source: mask secret-looking keys (token/secret/password/auth/jwt/
  api-key/credential/session-id/cookie/private) by default via new
  maskSensitiveKeys option (default true). Previously all localStorage keys —
  including auth tokens — were captured verbatim into AI context unless the
  app explicitly configured omitKeys/maskKeys.
- mcp page bridge: never post responses with a wildcard '*' targetOrigin.
  Previously an empty event.origin fell back to '*', which could broadcast
  context packets to any origin. Now falls back to the bridge window's own
  origin and drops the response when no origin is known, with a regression test.
- CI: add least-privilege permissions (contents: read) to the three workflows
  that ran with default token permissions (test_unit, test_e2e, static_quality).
icon-light-32x32.png and icon-dark-32x32.png were byte-identical 182KB copies
of avatar.png (not actually 32x32) and referenced nowhere in the repo.
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
askable Ready Ready Preview, Comment Jul 2, 2026 1:03am

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

@askable-ui/angular

npm i https://pkg.pr.new/@askable-ui/angular@362

@askable-ui/context

npm i https://pkg.pr.new/@askable-ui/context@362

@askable-ui/core

npm i https://pkg.pr.new/@askable-ui/core@362

@askable-ui/create-app

npm i https://pkg.pr.new/@askable-ui/create-app@362

@askable-ui/mcp

npm i https://pkg.pr.new/@askable-ui/mcp@362

@askable-ui/qwik

npm i https://pkg.pr.new/@askable-ui/qwik@362

@askable-ui/react

npm i https://pkg.pr.new/@askable-ui/react@362

@askable-ui/react-native

npm i https://pkg.pr.new/@askable-ui/react-native@362

@askable-ui/solid

npm i https://pkg.pr.new/@askable-ui/solid@362

@askable-ui/svelte

npm i https://pkg.pr.new/@askable-ui/svelte@362

@askable-ui/vue

npm i https://pkg.pr.new/@askable-ui/vue@362

@askable-ui/web-component

npm i https://pkg.pr.new/@askable-ui/web-component@362

commit: 0568882

@vamgan vamgan merged commit 40a3374 into main Jul 2, 2026
9 checks passed
@vamgan vamgan deleted the claude/security-audit-fixes branch July 2, 2026 01:07
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