Skip to content

Epic 1 hygiene - #166

Open
jgindin wants to merge 3 commits into
mainfrom
epic-1-hygiene
Open

Epic 1 hygiene#166
jgindin wants to merge 3 commits into
mainfrom
epic-1-hygiene

Conversation

@jgindin

@jgindin jgindin commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Description

First in a series of refactorings, intending to clean up the A2UI Composer code.

Security Hardening, Global Hygiene & Lifecycle Cleanup

  • Introduces SafeUrlValidatorService and DomainOriginVerificationService to eliminate unsafe resource URLs and enforce strict origin checks on iframe messaging.
  • Hardens ChatCoordinator prompt submission concurrency using RxJS stream locking to prevent overlapping LLM requests.
  • Implements lifecycle disposal (model.dispose()) in the Monaco editor and takeUntilDestroyed subscription cleanup across selectors.
  • Purges obsolete ACTIVE_DRAFT storage keys, dead mock-rules fixtures, and global console.error patching hacks.

Pre-launch Checklist

  • I signed the [CLA].
  • I read the [Contributors Guide].
  • I read the [Style Guide].
  • I have added updates to the [CHANGELOG].
  • I updated/added relevant documentation.
  • My code changes (if any) have tests.
  • If my branch is on fork, I have verified that scripts/e2e_test.sh passes.

Create SafeUrlValidatorService for http/https validation.
Create DomainOriginVerificationService for strict iframe networking validation.
Wire bypassSecurityTrustResourceUrl inside rendered-frame.ts through the rigorous URL validator.
Swap the check in preview-bridge.ts for the strict origin verification.
Fix LLM concurrency in ChatCoordinator submitPrompt.
Fix Monaco model.dispose() in a2ui-composer-monaco-editor.
Inject takeUntilDestroyed in api-key-selector.ts and renderer-selector.ts.
Delete debug/mock-rules/ entirely.
Rip out console.error patch hacks from ChatCoordinator.
Delete obsolete storage key ACTIVE_DRAFT.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces origin verification for the preview bridge, adds safe URL validation for the rendered frame, cleans up the deprecated mock rules component, and improves resource disposal and subscription management in the Monaco editor and settings selectors. The review feedback highlights critical security vulnerabilities in the origin verification logic—specifically, the unsafe acceptance of 'null' origins and unvalidated query parameters. Additionally, it recommends replacing the deprecated 'substr()' method with 'slice()' and retaining detailed validation error logs in the chat coordinator to avoid hindering debugging.

Comment thread bridge/src/domain-origin-verification.ts
Comment on lines +40 to +46
if (window.location.search) {
try {
const params = new URLSearchParams(window.location.search);
const expectedOrigin = params.get('origin');
if (expectedOrigin && eventOrigin === expectedOrigin) {
return true;
}

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.

security-high high

Trusting the origin query parameter directly without validating it against an allowlist or a trusted domain pattern is a security vulnerability. An attacker can frame this application, pass their own origin in the query parameter (e.g., ?origin=https://attacker.com), and bypass the origin check entirely. Please validate that expectedOrigin belongs to a trusted domain (such as localhost or your organization's trusted domains) before performing the comparison.

      if (window.location.search) {
        try {
          const params = new URLSearchParams(window.location.search);
          const expectedOrigin = params.get('origin');
          const isTrustedDomain = expectedOrigin && (
            expectedOrigin.startsWith("http://localhost:") ||
            expectedOrigin.endsWith(".google.com") ||
            expectedOrigin.endsWith(".google")
          );
          if (isTrustedDomain && eventOrigin === expectedOrigin) {
            return true;
          }
        } catch {

Comment thread bridge/src/domain-origin-verification.spec.ts
Comment thread shell/src/app/shared/monaco-editor/monaco-editor.ts
Comment thread shell/src/app/chat/chat-service/chat-coordinator.ts
@github-actions

Copy link
Copy Markdown
Contributor

⚡ A2UI Composer PR Preview

Your automated preview is successfully live (commit 2213101):
👉 Launch PR Preview

Note: This environment will be wiped automatically when the PR is merged or closed.

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