Skip to content

fix(security): close runtime XSS and object authorization gaps - #6098

Merged
bokelley merged 2 commits into
mainfrom
fix-runtime-xss-and-authz
Jul 30, 2026
Merged

fix(security): close runtime XSS and object authorization gaps#6098
bokelley merged 2 commits into
mainfrom
fix-runtime-xss-and-authz

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

  • close stored and runtime XSS paths across admin, member, registry, perspective, feed, and Addie rendering/writer flows
  • enforce ownership and global-admin boundaries for chat continuation, profile administration, portrait eligibility, previews, and approval transitions
  • centralize canonical external/member URL validation and add regression coverage for duplicate server and browser dataflows

Root cause

Untrusted stored strings were reused across multiple HTML and navigation sinks without one canonical validation boundary. Several resource IDs, organization IDs, and lifecycle states were also trusted without consistently binding them to the authenticated owner or required global-admin role.

Validation

  • security review gate: clean
  • testing review gate: clean
  • code review gate: ready to push
  • focused security suite: 193 tests passed across 17 files
  • staged pre-commit suite: 1,025 general tests and 4,919 server unit tests passed; 30 skipped
  • TypeScript typecheck and diff checks passed

No changeset is required because these are server/UI operational fixes with no protocol-package changes.

Comment thread server/public/perspective-url.js Fixed
@bokelley
bokelley marked this pull request as ready for review July 30, 2026 17:11
aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Jul 30, 2026

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve — systematic runtime-XSS and object-authorization hardening across admin/member/registry/perspective/feed/Addie surfaces.

What I checked:

  • Scope is server/UI only — no static/schemas/source/**, docs/reference/**, or dist/** touched, so no schema↔docs coherence, oneOf discriminator, or immutable-artifact concerns apply, and the omitted changeset is correct per the app/admin/Addie out-of-scope rule.
  • gated_paths: false; no no-auto-approve team match; first review of this PR.
  • high_risk: true but all reasons are (modified) under server/src/addie/** and server/src/routes/** — no (deleted) entries, and no Medium-or-higher finding lands on any modified high-risk file, so rows 3 and 5 do not fire.
  • Centralized URL validators (HTTPS-only member-profile-url, perspective-url) replace ad-hoc parsing at persistence/render boundaries; feedback writes bound to (thread_id, message_id); portrait serving and admin routes gated to owner/global-admin; curator model output crosses a fail-closed, retryable validation boundary. Substantial accompanying test coverage.

Findings: Only one Low finding (content-curator.ts:1257 — fail-closed retryable boundary, verified safe). No critical/high/medium findings survive review.

Decision table: rows 1–8 do not fire (no critical/high, gate not applicable, no deletions, no medium on modified high-risk file, no prior escalation, no team gate, fewer than three medium findings). Falls through to row 9 → approve.

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve — clean diff, no blocking or medium findings.

The delta since the prior clean pass is two files: an explicit window.getSafePerspectiveNavigationUrl export at perspective-url.js:12-14 and a new unit test covering it. The export is redundant in the browser (classic-script top-level functions already bind to window) but load-bearing for the test's new Function('window', source) harness, which scopes declarations locally. Validator logic is unchanged, no wire surface is touched, and the test assertion is correct.

No protocol surface (static/schemas/source/**, docs/reference/**, dist/**) is modified, so schema↔docs coherence, changeset, oneOf-discriminator, and released-artifact-immutability gates do not apply. The PR is app/server/site-scoped.

high_risk is true only via (modified) matches on server/src/addie/** and server/src/routes/**, but the reviewer surfaced no medium-or-higher concerns on those files, so the modification is presumed safe (per high-risk-flag guidance — do not escalate on the flag alone). gated_paths is false and no no-auto-approve team match. Prior decision was already approve.

Decision table: rows 1–8 do not fire (no critical/high, no medium, gate false, no deletions, no team gate). Falls through to row 9 → approve.

@bokelley
bokelley merged commit 0c6db1b into main Jul 30, 2026
15 checks passed
@bokelley
bokelley deleted the fix-runtime-xss-and-authz branch July 30, 2026 18:41
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.

1 participant