Skip to content

feat(extension-auth): accept Firefox identity redirect hosts for extension auth - #1999

Open
ManthanNimodiya wants to merge 2 commits into
CapSoftware:mainfrom
ManthanNimodiya:feat/extension-firefox-auth
Open

feat(extension-auth): accept Firefox identity redirect hosts for extension auth#1999
ManthanNimodiya wants to merge 2 commits into
CapSoftware:mainfrom
ManthanNimodiya:feat/extension-firefox-auth

Conversation

@ManthanNimodiya

@ManthanNimodiya ManthanNimodiya commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Firefox's identity.launchWebAuthFlow redirects to https://.extensions.allizom.org/.

Generalizes validateExtensionRedirectUri to a host-suffix table and adds optional CAP_FIREFOX_EXTENSION_ID (packages/env).

Chrome pinning and the localhost-dev escape hatch unchanged. Independent of the other PRs.
(For production later: the hash for gecko id extension@cap.so is 324e9362f26688ae2eb9a75d1beae53ef6b8d0d2.)

Greptile Summary

This PR adds Firefox redirect host support to extension auth. The main changes are:

  • Adds optional CAP_FIREFOX_EXTENSION_ID server configuration.
  • Generalizes identity redirect validation across Chromium and Firefox host suffixes.
  • Normalizes the configured extension id before comparing it with the redirect host.
  • Updates the consent page heading to use browser-neutral wording.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
packages/env/server.ts Adds the optional Firefox extension redirect id to the server env schema.
packages/web-backend/src/Extension/Http.ts Validates extension auth redirects through a browser suffix table and compares against the normalized configured id.

Reviews (2): Last reviewed commit: "fix(extension-auth): normalize configure..." | Re-trigger Greptile

Context used:

  • Context used - CLAUDE.md (source)
  • Context used - AGENTS.md (source)

);
const configuredExtensionId = serverEnv().CAP_CHROME_EXTENSION_ID;
const extensionId = url.hostname.slice(0, -identityHost.suffix.length);
const configuredExtensionId = identityHost.getConfiguredExtensionId();

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.

P2 Mixed-Case Firefox Id Rejection

URL.hostname is normalized to lowercase before extensionId is sliced, but the new Firefox id comes straight from CAP_FIREFOX_EXTENSION_ID. If that env var is copied with uppercase characters, the configured-id check rejects the real Firefox redirect host and the extension auth flow always returns a bad request.

Suggested change
const configuredExtensionId = identityHost.getConfiguredExtensionId();
const configuredExtensionId = identityHost
.getConfiguredExtensionId()
?.toLowerCase();
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/web-backend/src/Extension/Http.ts
Line: 51

Comment:
**Mixed-Case Firefox Id Rejection**

`URL.hostname` is normalized to lowercase before `extensionId` is sliced, but the new Firefox id comes straight from `CAP_FIREFOX_EXTENSION_ID`. If that env var is copied with uppercase characters, the configured-id check rejects the real Firefox redirect host and the extension auth flow always returns a bad request.

```suggestion
		const configuredExtensionId = identityHost
			.getConfiguredExtensionId()
			?.toLowerCase();
```

How can I resolve this? If you propose a fix, please make it concise.

const identityHost = IDENTITY_REDIRECT_HOSTS.find(({ suffix }) =>
url.hostname.endsWith(suffix),
);
if (url.protocol !== "https:" || !identityHost) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Might be worth rejecting non-default ports / credentials here to keep the redirect URI shape tight (and avoid surprises if browser behavior changes).

Suggested change
if (url.protocol !== "https:" || !identityHost) {
if (
url.protocol !== "https:" ||
url.port !== "" ||
url.username ||
url.password ||
!identityHost
) {
return yield* new HttpApiError.BadRequest();
}

Comment on lines +50 to +51
const extensionId = url.hostname.slice(0, -identityHost.suffix.length);
const configuredExtensionId = identityHost.getConfiguredExtensionId();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Since the comment says the leading label identifies the extension installation, it could be good to explicitly reject multi-label hosts (e.g. a.b.chromiumapp.org).

Suggested change
const extensionId = url.hostname.slice(0, -identityHost.suffix.length);
const configuredExtensionId = identityHost.getConfiguredExtensionId();
const extensionId = url.hostname.slice(0, -identityHost.suffix.length);
if (extensionId.includes(".")) {
return yield* new HttpApiError.BadRequest();
}
const configuredExtensionId = identityHost.getConfiguredExtensionId();

@ManthanNimodiya

Copy link
Copy Markdown
Contributor Author

@greptileai

@ManthanNimodiya
ManthanNimodiya force-pushed the feat/extension-firefox-auth branch from f6d875c to 8c52575 Compare August 6, 2026 05:25
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