Skip to content

🛡️ Sentinel: Fix insecure postMessage origin in OAuth redirects#15

Open
AGI-Corporation wants to merge 4 commits intomainfrom
sentinel/fix-insecure-postmessage-origin-redirects-843941654461830414
Open

🛡️ Sentinel: Fix insecure postMessage origin in OAuth redirects#15
AGI-Corporation wants to merge 4 commits intomainfrom
sentinel/fix-insecure-postmessage-origin-redirects-843941654461830414

Conversation

@AGI-Corporation
Copy link
Copy Markdown
Owner

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

🛡️ Sentinel: [HIGH] Fix insecure postMessage origin in OAuth redirects

Restricted the target origin of window.postMessage in both server-side and client-side OAuth redirect handlers. Using a wildcard origin ('*') is insecure as it allows sensitive authorization codes to be intercepted by malicious origins.

  • In packages/server/api/src/app/app.ts, the /redirect route now resolves the platform-specific frontend origin.
  • In packages/react-ui/src/app/routes/redirect.tsx, the targetOrigin is restricted to window.location.origin.
  • Updated .jules/sentinel.md with details of this vulnerability and prevention strategy.

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

Summary by CodeRabbit

  • Bug Fixes

    • Tightened origin validation in OAuth redirect flows, restricting postMessage targets to specific origins and improving security.
    • Fixed typo in the redirect success message.
  • Documentation

    • Added security guidance documenting the vulnerability, recommending dynamic origin resolution for multi-tenant setups and safer targetOrigin handling.

Restricted the target origin of `window.postMessage` in both server-side and client-side OAuth redirect handlers. Using a wildcard origin (`'*'`) is insecure as it allows sensitive authorization codes to be intercepted by malicious origins.

- In `packages/server/api/src/app/app.ts`, the `/redirect` route now resolves the platform-specific frontend origin.
- In `packages/react-ui/src/app/routes/redirect.tsx`, the `targetOrigin` is restricted to `window.location.origin`.
- Updated `.jules/sentinel.md` with details of this vulnerability and prevention strategy.

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 11, 2026

Warning

Rate limit exceeded

@AGI-Corporation has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 25 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4e8b6bf9-7aa1-410b-829d-73d27abd33d8

📥 Commits

Reviewing files that changed from the base of the PR and between a7f4aa0 and 8013e62.

📒 Files selected for processing (1)
  • packages/react-ui/src/lib/oauth2-utils.ts
📝 Walkthrough

Walkthrough

Client and server OAuth redirect flows were hardened by replacing wildcard postMessage origins with explicitly resolved origins; origin validation on message receipt was tightened. A new security doc .jules/sentinel.md describing the issue and mitigation guidance was added. (50 words)

Changes

Cohort / File(s) Summary
Security Vulnerability Documentation
​.jules/sentinel.md
Added a security note describing the high-severity postMessage wildcard-origin vulnerability in OAuth redirect flows and guidance to resolve/limit targetOrigin in multi-tenant setups.
Client redirect handler
packages/react-ui/src/app/routes/redirect.tsx
Replaced postMessage targetOrigin '*' with window.location.origin.
Client message validation
packages/react-ui/src/lib/oauth2-utils.ts
Tightened origin check: derive expectedOrigin from redirectUrl and require exact equality (event.origin === expectedOrigin) when accepting code from postMessage.
Server redirect handler
packages/server/api/src/app/app.ts
Resolve platform frontend URL via domainHelper.getPublicUrl({ platformId }), compute targetOrigin from that URL and use it in postMessage instead of '*'; fixed a typo in the success text.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sniffed the air where wildcards flew,

The message sent to anyone and new.
Now origins match, the gate is tight,
Popups whisper only to the right.
Hooray — secure hops through the night 🥕🔒

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
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.
Description check ❓ Inconclusive The description explains what was fixed and provides implementation details across files, but lacks the structured sections (What does this PR do, How the Feature Works, Relevant User Scenarios) specified in the template. Restructure the description to follow the template format: add a 'What does this PR do' section, explain how the security fix works, and include relevant use cases or references to justify the changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main security fix (restricting postMessage origin in OAuth redirects), directly matching the primary change across all modified files.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sentinel/fix-insecure-postmessage-origin-redirects-843941654461830414

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: 46c64ebbe3

ℹ️ 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".

Comment on lines +253 to +255
const platformId = await platformUtils.getPlatformIdForRequest(request)
const frontendUrl = await domainHelper.getPublicUrl({ platformId })
const targetOrigin = new URL(frontendUrl).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 Preserve opener origin for /redirect responses

Deriving targetOrigin from domainHelper.getPublicUrl({ platformId }) here can send the OAuth code to the wrong origin in cloud custom-domain setups that use AP_INTERNAL_URL: THIRD_PARTY_AUTH_PROVIDER_REDIRECT_URL is generated via getInternalUrl (shared/internal host), so this /redirect request may not map to a tenant host, getPlatformIdForRequest falls back to null, and the handler posts to the default frontend origin instead of the tenant opener origin. In that environment, window.opener.postMessage is blocked by origin mismatch and the OAuth/SSO popup never returns a code.

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/react-ui/src/app/routes/redirect.tsx (1)

11-17: Security fix looks correct, but consider hardening the receiver validation.

The change from '*' to window.location.origin correctly restricts the postMessage target. However, note that the message receiver in packages/react-ui/src/lib/oauth2-utils.ts (lines 78-79) uses redirectUrl.startsWith(event.origin) which is a weak validation—it could accept messages from origins sharing a common prefix (e.g., https://app.example.com.attacker.com would pass if redirectUrl starts with https://app.example.com).

Consider tightening the receiver validation to use exact origin matching:

new URL(redirectUrl).origin === event.origin
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-ui/src/app/routes/redirect.tsx` around lines 11 - 17, The
receiver currently validates origins using the startsWith check (see
redirectUrl.startsWith(event.origin) in
packages/react-ui/src/lib/oauth2-utils.ts); replace that weak prefix check with
an exact origin comparison by deriving the origin from redirectUrl (using the
URL API) and comparing it strictly to event.origin so only an exact match is
accepted.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/server/api/src/app/app.ts`:
- Around line 253-261: Add the missing import for platformUtils used in the
handler: import { platformUtils } from './platform/platform.utils'; this will
ensure platformUtils.getPlatformIdForRequest(request) resolves; update the top
of the file where other imports are declared so platformUtils is available
before its use in the code that calls platformUtils.getPlatformIdForRequest and
remove any linter/unused-import warnings if needed.

---

Nitpick comments:
In `@packages/react-ui/src/app/routes/redirect.tsx`:
- Around line 11-17: The receiver currently validates origins using the
startsWith check (see redirectUrl.startsWith(event.origin) in
packages/react-ui/src/lib/oauth2-utils.ts); replace that weak prefix check with
an exact origin comparison by deriving the origin from redirectUrl (using the
URL API) and comparing it strictly to event.origin so only an exact match is
accepted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 83db884e-e75d-4d3c-aa6f-5af1f6a5136b

📥 Commits

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

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

Comment thread packages/server/api/src/app/app.ts
This PR addresses a security vulnerability where `window.postMessage` was using a wildcard origin (`'*'`) or loose validation (`startsWith`), potentially leaking OAuth authorization codes to malicious origins.

Key changes:
- Restricted `targetOrigin` in server-side `/redirect` route to the platform's public frontend origin.
- Restricted `targetOrigin` in client-side `RedirectPage` to `window.location.origin`.
- Improved `postMessage` listener in `oauth2-utils.ts` to use strict origin equality and moved origin calculation for better performance/robustness.
- Fixed a typo in the server response message.
- Added missing import for `platformUtils` in `app.ts`.

Closes #security-sentinel-01 (Sentinel security enhancement)

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

🧹 Nitpick comments (1)
packages/react-ui/src/lib/oauth2-utils.ts (1)

74-88: Good security hardening with strict origin equality.

The change from startsWith to exact origin equality is the correct fix. The previous check was vulnerable to origin spoofing (e.g., https://trusted.com.attacker.com would pass a startsWith('https://trusted.com') check).

One consideration: new URL(redirectUrl) on line 76 will throw a TypeError if redirectUrl is malformed. This would result in an unhandled promise rejection since the error propagates up from getCode. The callers appear to always pass valid URLs from configuration, but you may want defensive handling:

♻️ Optional: Add defensive URL parsing
 function getCode(redirectUrl: string): Promise<string> {
   return new Promise<string>((resolve) => {
-    const expectedOrigin = redirectUrl ? new URL(redirectUrl).origin : null;
+    let expectedOrigin: string | null = null;
+    try {
+      expectedOrigin = redirectUrl ? new URL(redirectUrl).origin : null;
+    } catch {
+      console.error('Invalid redirectUrl for OAuth origin validation:', redirectUrl);
+    }
     window.addEventListener('message', function handler(event) {
🤖 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 - 88, getCode
currently calls new URL(redirectUrl) which will throw for malformed redirectUrl
and cause an unhandled rejection; update getCode to accept a reject callback in
the Promise, wrap the new URL(redirectUrl) parsing in a try/catch and call
reject(new TypeError(...)) or reject(err) if parsing fails, and early-return so
the message event handler is not registered; reference getCode, new
URL(redirectUrl), expectedOrigin, and the window.addEventListener('message',
handler) block when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/react-ui/src/lib/oauth2-utils.ts`:
- Around line 74-88: getCode currently calls new URL(redirectUrl) which will
throw for malformed redirectUrl and cause an unhandled rejection; update getCode
to accept a reject callback in the Promise, wrap the new URL(redirectUrl)
parsing in a try/catch and call reject(new TypeError(...)) or reject(err) if
parsing fails, and early-return so the message event handler is not registered;
reference getCode, new URL(redirectUrl), expectedOrigin, and the
window.addEventListener('message', handler) block when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ad6920c9-099d-4fbf-a2ed-d670bb0a0f5e

📥 Commits

Reviewing files that changed from the base of the PR and between 46c64eb and a7f4aa0.

📒 Files selected for processing (2)
  • packages/react-ui/src/lib/oauth2-utils.ts
  • packages/server/api/src/app/app.ts

google-labs-jules bot and others added 2 commits March 11, 2026 08:21
Restricted the target origin of `window.postMessage` in both server-side and client-side OAuth redirect handlers. Using a wildcard origin (`'*'`) or loose validation (`startsWith`) is insecure as it allows sensitive authorization codes to be intercepted by malicious origins.

- In `packages/server/api/src/app/app.ts`, the `/redirect` route now resolves the platform-specific frontend origin.
- In `packages/react-ui/src/app/routes/redirect.tsx`, the `targetOrigin` is restricted to `window.location.origin`.
- Improved `postMessage` listener in `oauth2-utils.ts` to use strict origin equality and moved origin calculation for better performance/robustness.
- Fixed a typo in the server response message.
- Added missing import for `platformUtils` in `app.ts`.

Closes #1

Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com>
Restricted the target origin of `window.postMessage` in both server-side and client-side OAuth redirect handlers. Using a wildcard origin (`'*'`) or loose validation (`startsWith`) is insecure as it allows sensitive authorization codes to be intercepted by malicious origins.

- In `packages/server/api/src/app/app.ts`, the `/redirect` route now resolves the platform-specific frontend origin.
- In `packages/react-ui/src/app/routes/redirect.tsx`, the `targetOrigin` is restricted to `window.location.origin`.
- Improved `postMessage` listener in `oauth2-utils.ts` to use strict origin equality and added error handling for URL parsing.
- Fixed a typo in the server response message.
- Added missing import for `platformUtils` in `app.ts`.

Closes #1

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