Skip to content

fix(security): harden SSRF, upgrades, bind policy, and mutation UX - #201

Draft
goniszewski wants to merge 3 commits into
developfrom
cursor/security-hardening-review-fixes-75ce
Draft

fix(security): harden SSRF, upgrades, bind policy, and mutation UX#201
goniszewski wants to merge 3 commits into
developfrom
cursor/security-hardening-review-fixes-75ce

Conversation

@goniszewski

@goniszewski goniszewski commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the comprehensive code-review hardening items for Grimoire’s critical paths while staying inside the local-first / loopback threat model.

Daemon / security

  • Manual redirect validation for page fetch and update checks (safe-fetch) so private redirect targets are never contacted
  • GET /updates/check rejects arbitrary source query params (default/env source only)
  • Remote upgrades require HTTPS release bases, detached signatures, optional fingerprint pinning via LITTLEIMP_UPGRADE_SIGNING_KEY_FINGERPRINTS, and download size caps; --allow-unsigned / LITTLEIMP_ALLOW_UNSIGNED_UPGRADE=1 is an explicit escape hatch
  • Bind-host policy refuses non-loopback binds unless container context or LITTLEIMP_ALLOW_NON_LOOPBACK_BIND=1 is set, with a loud warning
  • Shared public URL validation rejects embedded credentials across bookmarks / capture / MCP / import; logs redact credentials
  • Default JSON body limits on mutating routes
  • HTTP restore no longer accepts allow_unsafe_no_checksum
  • Concurrent same-URL create races return the existing bookmark instead of a raw UNIQUE error

Frontend

  • Mutations await daemon confirmation before success toasts / dialog close
  • Broader cache invalidation on add/delete
  • Bulk category move uses category IDs; list/search prefer category_id over name
  • Safe http(s) checks before window.open / href
  • Route-level ErrorBoundary
  • Bookmarklet embeds token/URL via JSON.stringify
  • testAiConnection / export download / update-check go through api.ts

Docs

  • API contract regenerated; security boundaries / backup design updated
  • Task report: docs/task-reports/2026/07/2026-07-22-security-hardening-review-fixes/

Test plan

  • Focused daemon tests (fetch redirects, public-url, bind-host, updates, CLI upgrade signatures)
  • npm run check (lint, type-check, frontend + daemon tests, docs:api:check, build)
  • npm run test:e2e (25 passed; revalidated the invalid-URL dialog assertion after copy tweak)
Open in Web Open in Cursor 

cursoragent and others added 3 commits July 22, 2026 17:26
Address the comprehensive code-review findings: validate redirects before
following them, reject arbitrary HTTP update sources, require signed remote
upgrades, fail closed on non-loopback binds outside containers, reject URL
credentials consistently, apply default body limits, drop unsafe restore
bypass from HTTP, and make frontend mutations confirm before success UX.

Co-authored-by: Robert Goniszewski <goniszewski@users.noreply.github.com>
Prefer category_id-only list/search params in hook tests, and use a
concrete ApiUpdateCheckResult shape to avoid deep DTO instantiation.

Co-authored-by: Robert Goniszewski <goniszewski@users.noreply.github.com>
Preserve a "valid URL" phrase in the dialog error so existing journey
coverage continues to match the safer http(s)/no-credentials check.

Co-authored-by: Robert Goniszewski <goniszewski@users.noreply.github.com>
@sonarqubecloud

Copy link
Copy Markdown

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