fix(connectors): allowlist provider authorization endpoints
This commit is contained in:
parent
8bac89b1a6
commit
e220a51eab
|
|
@ -115,11 +115,35 @@ describe("Paperclip Cloud connector", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("accepts the fixed Google authorization endpoint for Google profiles", async () => {
|
||||
const keys = config();
|
||||
const connector = createPaperclipCloudConnector({
|
||||
config: keys.config,
|
||||
request: vi.fn(async () => Response.json({
|
||||
confirmationUrl: "https://my.example.test/connections/confirm?session=broker-state",
|
||||
authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth?client_id=client&state=broker-state",
|
||||
expiresAt: "2099-08-21T20:00:00.000Z",
|
||||
})) as typeof fetch,
|
||||
});
|
||||
|
||||
await expect(connector.startAuthorization({
|
||||
subject,
|
||||
companyId,
|
||||
profile: "gmail.draft",
|
||||
returnUri: "https://paperclip.example.test/api/tools/oauth/cloud-connector/callback",
|
||||
returnState: "state-direct-google",
|
||||
})).resolves.toMatchObject({
|
||||
authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth?client_id=client&state=broker-state",
|
||||
});
|
||||
});
|
||||
|
||||
it.each([
|
||||
["non-string", { href: "https://github.com/login/oauth/authorize" }],
|
||||
["plaintext HTTP", "http://github.com/login/oauth/authorize"],
|
||||
["embedded credentials", "https://user:password@github.com/login/oauth/authorize"],
|
||||
["fragment", "https://github.com/login/oauth/authorize#unexpected"],
|
||||
["unapproved HTTPS origin", "https://attacker.example.test/login/oauth/authorize"],
|
||||
["unapproved provider path", "https://github.com/session/authorize"],
|
||||
["not a URL", "not-a-url"],
|
||||
])("rejects a malformed direct provider URL: %s", async (_label, authorizationUrl) => {
|
||||
const keys = config();
|
||||
|
|
|
|||
|
|
@ -380,6 +380,7 @@ export function createPaperclipCloudConnector(input: {
|
|||
|| authorizationUrl.username
|
||||
|| authorizationUrl.password
|
||||
|| authorizationUrl.hash
|
||||
|| !isExpectedProviderAuthorizationUrl(profile, authorizationUrl)
|
||||
) {
|
||||
throw new PaperclipCloudConnectorError("Paperclip Cloud connector returned an invalid provider URL", "CONNECTOR_BAD_RESPONSE");
|
||||
}
|
||||
|
|
@ -678,6 +679,16 @@ function connectorProfileDefinition(profile: PaperclipCloudConnectorProfileId):
|
|||
return { provider: "google", scopes: GOOGLE_WORKSPACE_CONNECTOR_PROFILES[profile].scopes };
|
||||
}
|
||||
|
||||
function isExpectedProviderAuthorizationUrl(
|
||||
profile: PaperclipCloudConnectorProfileId,
|
||||
url: URL,
|
||||
): boolean {
|
||||
if (isGitHubConnectorProfileId(profile)) {
|
||||
return url.origin === "https://github.com" && url.pathname === "/login/oauth/authorize";
|
||||
}
|
||||
return url.origin === "https://accounts.google.com" && url.pathname === "/o/oauth2/v2/auth";
|
||||
}
|
||||
|
||||
function isPaperclipCloudConnectorProfileId(value: string): value is PaperclipCloudConnectorProfileId {
|
||||
return isGoogleWorkspaceConnectorProfileId(value) || isGitHubConnectorProfileId(value);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue