Skip to content

🛡️ Sentinel: Secure OAuth2 postMessage target origin and origin validation#14

Open
AGI-Corporation wants to merge 4 commits intomainfrom
sentinel-fix-postmessage-target-origin-and-validation-v2-14274471365459152318
Open

🛡️ Sentinel: Secure OAuth2 postMessage target origin and origin validation#14
AGI-Corporation wants to merge 4 commits intomainfrom
sentinel-fix-postmessage-target-origin-and-validation-v2-14274471365459152318

Conversation

@AGI-Corporation
Copy link
Copy Markdown
Owner

@AGI-Corporation AGI-Corporation commented Mar 10, 2026

🛡️ Sentinel Security Fix: OAuth2 postMessage Hardening

🚨 Severity: HIGH
💡 Vulnerability: Insecure postMessage target origins and origin validation.

  • The /redirect route and frontend redirect page were using '*' as the targetOrigin for postMessage, which could allow a malicious site to intercept the OAuth2 code.
  • The frontend was using .startsWith(event.origin) to validate incoming messages, which is vulnerable to domain-shadowing attacks (e.g., trusted.com.malicious.com passes a check for trusted.com).

🎯 Impact: An attacker could potentially steal OAuth2 authorization codes, leading to account takeover or unauthorized access to third-party services.

🔧 Fix:

  1. Updated packages/server/api/src/app/app.ts to resolve the trusted frontend origin using platformUtils.getPlatformIdForRequest and domainHelper.getPublicUrl, then used it as the targetOrigin for postMessage.
  2. Updated packages/react-ui/src/app/routes/redirect.tsx to use window.location.origin as the targetOrigin.
  3. Updated packages/react-ui/src/lib/oauth2-utils.ts to use strict equality (event.origin === expectedOrigin) for origin validation.

Verification:

  • Verified changes via read_file to ensure correct logic and imports.
  • Ran targeted linting using npx eslint to confirm no syntax or basic type errors were introduced.
  • Verified that the pnpm-lock.yaml file was removed to keep the PR focused on security changes.

PR created automatically by Jules for task 14274471365459152318 started by @AGI-Corporation

Summary by CodeRabbit

  • Security
    • Enhanced OAuth2 and redirect authentication security by restricting message delivery to verified application origins instead of allowing all origins.
    • Strengthened origin validation to ensure authentication messages are only processed from trusted sources, preventing unauthorized cross-origin access attempts.

…ation

- Restricted backend and frontend OAuth redirect `postMessage` target origins to the trusted application origin instead of using the wildcard `'*'`.
- Hardened frontend origin validation for `postMessage` events by replacing insecure `startsWith` matching with strict equality checks using resolved origins.
- Resolved missing `platformUtils` import in `packages/server/api/src/app/app.ts`.
- Cleaned up environment noise by removing the auto-generated `pnpm-lock.yaml`.

Security Impact: Prevents interception of sensitive authorization codes by malicious sites and mitigates domain-shadowing attacks.

Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 10, 2026

📝 Walkthrough

Walkthrough

The changes implement stricter origin validation for postMessage communications across the authentication flow. Wildcard origin targeting ("*") is replaced with specific origin matching derived from the frontend URL, enhancing security by preventing unintended message delivery.

Changes

Cohort / File(s) Summary
Client-side OAuth2 Origin Validation
packages/react-ui/src/app/routes/redirect.tsx, packages/react-ui/src/lib/oauth2-utils.ts
Updated postMessage origin targeting and OAuth2 message validation. redirect.tsx now targets window.location.origin instead of wildcard. oauth2-utils.ts replaces prefix-based origin checking (startsWith) with exact origin match comparison using URL parsing.
Server-side Origin Resolution
packages/server/api/src/app/app.ts
Added platform-aware origin resolution in the /redirect route handler. Retrieves platformId via platformUtils, resolves frontendUrl using domainHelper, and derives targetOrigin for postMessage targeting instead of using wildcard.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Through origins we hop with care,
No wildcards floating in the air,
Each message now knows where to go,
With platform URLs all in a row,
Security strengthened with each check—hooray! 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers vulnerability details, impact, fixes applied, and verification steps, but lacks required template sections: 'How the Feature Works', 'Relevant User Scenarios', and proper 'Fixes #' issue reference. Restructure the description to match the template: add sections for 'Explain How the Feature Works' (with optional video), 'Relevant User Scenarios' (with issue/ticket references), and include 'Fixes #' with the associated issue number.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main security changes: hardening OAuth2 postMessage by securing target origins and origin validation, which aligns with all three file modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sentinel-fix-postmessage-target-origin-and-validation-v2-14274471365459152318

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d75d84fbe4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

code: code,
},
'*',
window.location.origin,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore cross-origin opener messaging for cloud OAuth redirects

Setting postMessage targetOrigin to window.location.origin means the popup can only message an opener on the same origin, but the cloud OAuth2 flow uses https://secrets.activepieces.com/redirect as the redirect URL (packages/react-ui/src/app/connections/oauth2-connection-settings.tsx lines 96-99) while the opener is the main app domain, so the browser drops the message and the OAuth popup never returns a code. Use the expected opener origin (or a configured trusted origin) instead of the popup's own origin.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/react-ui/src/lib/oauth2-utils.ts (1)

74-89: ⚠️ Potential issue | 🟠 Major

Strict origin validation is correct, but new URL(redirectUrl) can throw before the guard.

The security fix using strict equality (===) instead of startsWith is correct and prevents domain-shadowing attacks. However, new URL(redirectUrl) on line 77 executes before the redirectUrl && check on line 79. If redirectUrl is empty, undefined, or malformed (see callers in oauth2-connection-settings.tsx and third-party-logins.tsx where it comes from flags), this throws a TypeError and the promise never resolves, causing the OAuth flow to hang silently.

🛡️ Proposed fix: validate and parse URL before adding listener or inside guard
 function getCode(redirectUrl: string): Promise<string> {
+  let expectedOrigin: string;
+  try {
+    expectedOrigin = new URL(redirectUrl).origin;
+  } catch {
+    return Promise.reject(new Error('Invalid redirectUrl provided'));
+  }
   return new Promise<string>((resolve) => {
     window.addEventListener('message', function handler(event) {
-      const expectedOrigin = new URL(redirectUrl).origin;
       if (
-        redirectUrl &&
         event.origin === expectedOrigin &&
         event.data['code']
       ) {
         resolve(decodeURIComponent(event.data.code));
         currentPopup?.close();
         window.removeEventListener('message', handler);
       }
     });
   });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-ui/src/lib/oauth2-utils.ts` around lines 74 - 89, In getCode,
new URL(redirectUrl) is called before checking redirectUrl and can throw,
leaving the promise unresolved; validate and parse redirectUrl before adding the
message listener: first check redirectUrl is truthy, attempt to construct new
URL(redirectUrl) in a try/catch to obtain expectedOrigin (or reject the Promise
immediately on failure), only then add window.addEventListener; alternatively
parse expectedOrigin inside the handler with a try/catch and if parsing fails
reject/cleanup (close currentPopup and remove the handler) so the Promise never
hangs; refer to getCode, redirectUrl, currentPopup, and the message handler to
locate places to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/react-ui/src/lib/oauth2-utils.ts`:
- Around line 74-89: In getCode, new URL(redirectUrl) is called before checking
redirectUrl and can throw, leaving the promise unresolved; validate and parse
redirectUrl before adding the message listener: first check redirectUrl is
truthy, attempt to construct new URL(redirectUrl) in a try/catch to obtain
expectedOrigin (or reject the Promise immediately on failure), only then add
window.addEventListener; alternatively parse expectedOrigin inside the handler
with a try/catch and if parsing fails reject/cleanup (close currentPopup and
remove the handler) so the Promise never hangs; refer to getCode, redirectUrl,
currentPopup, and the message handler to locate places to change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0f3aea06-c163-4842-9041-dd737d35ddb9

📥 Commits

Reviewing files that changed from the base of the PR and between f61e720 and d75d84f.

📒 Files selected for processing (4)
  • .jules/sentinel.md
  • packages/react-ui/src/app/routes/redirect.tsx
  • packages/react-ui/src/lib/oauth2-utils.ts
  • packages/server/api/src/app/app.ts

google-labs-jules bot and others added 3 commits March 10, 2026 08:04
…ation

- Restricted backend and frontend OAuth redirect `postMessage` target origins to the trusted application origin instead of using the wildcard `'*'`.
- Hardened frontend origin validation for `postMessage` events by replacing insecure `startsWith` matching with strict equality checks using resolved origins.
- Resolved missing `platformUtils` import in `packages/server/api/src/app/app.ts`.
- Cleaned up environment noise by removing the auto-generated `pnpm-lock.yaml`.

Security Impact: Prevents interception of sensitive authorization codes by malicious sites and mitigates domain-shadowing attacks.

Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com>
…ation

- Restricted backend and frontend OAuth redirect `postMessage` target origins to the trusted application origin instead of using the wildcard `'*'`.
- Hardened frontend origin validation for `postMessage` events by replacing insecure `startsWith` matching with strict equality checks using resolved origins.
- Resolved missing `platformUtils` import in `packages/server/api/src/app/app.ts`.
- Cleaned up environment noise by removing the auto-generated `pnpm-lock.yaml`.

Security Impact: Prevents interception of sensitive authorization codes by malicious sites and mitigates domain-shadowing attacks.

Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com>
…ation

- Restricted backend and frontend OAuth redirect `postMessage` target origins to the trusted application origin instead of using the wildcard `'*'`.
- Hardened frontend origin validation for `postMessage` events by replacing insecure `startsWith` matching with strict equality checks using resolved origins.
- Resolved missing `platformUtils` import in `packages/server/api/src/app/app.ts`.
- Cleaned up environment noise by removing the auto-generated `pnpm-lock.yaml`.

Security Impact: Prevents interception of sensitive authorization codes by malicious sites and mitigates domain-shadowing attacks.

Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com>
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