From cd71aab47af6ab3616c2b78944d99f81d10ed958 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 09:01:06 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20Fix=20i?= =?UTF-8?q?nsecure=20postMessage=20target=20origins=20in=20OAuth2=20flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Restricted postMessage target origin in redirect.tsx and server-side /redirect endpoint to prevent leaking authorization codes. - Tightened origin verification in oauth2-utils.ts to use strict equality, preventing potential origin bypasses. - Use domainHelper to dynamically resolve the trusted frontend origin on the server. Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com> --- .jules/sentinel.md | 0 packages/react-ui/src/app/routes/redirect.tsx | 2 +- packages/react-ui/src/lib/oauth2-utils.ts | 3 ++- packages/server/api/src/app/app.ts | 4 +++- 4 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/react-ui/src/app/routes/redirect.tsx b/packages/react-ui/src/app/routes/redirect.tsx index 0d7ccb0ed7..74db8bfcd4 100644 --- a/packages/react-ui/src/app/routes/redirect.tsx +++ b/packages/react-ui/src/app/routes/redirect.tsx @@ -13,7 +13,7 @@ const RedirectPage: React.FC = React.memo(() => { { code: code, }, - '*', + window.location.origin, ); } }, [location.search]); diff --git a/packages/react-ui/src/lib/oauth2-utils.ts b/packages/react-ui/src/lib/oauth2-utils.ts index 7b9ca004e9..942ad7fa2f 100644 --- a/packages/react-ui/src/lib/oauth2-utils.ts +++ b/packages/react-ui/src/lib/oauth2-utils.ts @@ -74,9 +74,10 @@ function constructUrl(params: OAuth2PopupParams, pckeChallenge: string) { function getCode(redirectUrl: string): Promise { return new Promise((resolve) => { window.addEventListener('message', function handler(event) { + const expectedOrigin = new URL(redirectUrl).origin; if ( redirectUrl && - redirectUrl.startsWith(event.origin) && + event.origin === expectedOrigin && event.data['code'] ) { resolve(decodeURIComponent(event.data.code)); diff --git a/packages/server/api/src/app/app.ts b/packages/server/api/src/app/app.ts index 671220419f..bd60aa922b 100644 --- a/packages/server/api/src/app/app.ts +++ b/packages/server/api/src/app/app.ts @@ -250,12 +250,14 @@ export const setupApp = async (app: FastifyInstance): Promise = return reply.send('The code is missing in url') } else { + const frontendUrl = await domainHelper.getPublicUrl({ platformId: null }) + const frontendOrigin = new URL(frontendUrl).origin return reply .type('text/html') .send( ` Redirect succuesfully, this window should close now`, + )}' }, '${frontendOrigin}')} Redirect succuesfully, this window should close now`, ) } }, From 764c2535f9f55b8b340581b5b02547c449771126 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 09:14:38 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20Fix=20i?= =?UTF-8?q?nsecure=20postMessage=20target=20origins=20in=20OAuth2=20flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Restricted postMessage target origin in redirect.tsx and server-side /redirect endpoint to prevent leaking authorization codes. - Tightened origin verification in oauth2-utils.ts to use strict equality, preventing potential origin bypasses. - Use domainHelper to dynamically resolve the trusted frontend origin on the server and ensure only the origin component is used. Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index e69de29bb2..5dbcf8a14c 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2025-05-15 - [Secure postMessage origins in OAuth2 flow] +**Vulnerability:** Use of `*` wildcard as target origin in `window.postMessage` during OAuth2 redirection, which could leak authorization codes to malicious windows. +**Learning:** The codebase has multiple places (frontend and backend) where `postMessage` is used to communicate the OAuth code back to the opener. +**Prevention:** Use `window.location.origin` on the client and `domainHelper.getPublicUrl` on the server to resolve the trusted frontend origin. Always extract only the origin (scheme + host + port) using `new URL(url).origin` to ensure strict matching by the browser.