1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-06 12:02:40 +03:00

OIDC: only pass logo_uri, policy_uri, tos_uri if they conform to "common base" (#4748)

* OIDC: only pass logo_uri, policy_uri, tos_uri if they conform to "common base"

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2025-03-13 14:47:09 +00:00
committed by GitHub
parent 9f9be701e7
commit b14cc82682
2 changed files with 41 additions and 6 deletions

View File

@@ -29,8 +29,8 @@ describe("registerOidcClient()", () => {
redirectUris: [baseUrl], redirectUris: [baseUrl],
clientName, clientName,
applicationType: "web", applicationType: "web",
tosUri: "http://tos-uri", tosUri: "https://just.testing/tos",
policyUri: "http://policy-uri", policyUri: "https://policy.just.testing",
contacts: ["admin@example.com"], contacts: ["admin@example.com"],
}; };
const dynamicClientId = "xyz789"; const dynamicClientId = "xyz789";
@@ -67,6 +67,8 @@ describe("registerOidcClient()", () => {
id_token_signed_response_alg: "RS256", id_token_signed_response_alg: "RS256",
token_endpoint_auth_method: "none", token_endpoint_auth_method: "none",
application_type: "web", application_type: "web",
tos_uri: "https://just.testing/tos",
policy_uri: "https://policy.just.testing",
}), }),
); );
}); });
@@ -114,4 +116,24 @@ describe("registerOidcClient()", () => {
), ),
).rejects.toThrow(OidcError.DynamicRegistrationNotSupported); ).rejects.toThrow(OidcError.DynamicRegistrationNotSupported);
}); });
it("should filter out invalid URIs", async () => {
fetchMockJest.post(delegatedAuthConfig.registration_endpoint!, {
status: 200,
body: JSON.stringify({ client_id: dynamicClientId }),
});
expect(
await registerOidcClient(delegatedAuthConfig, {
...metadata,
tosUri: "http://just.testing/tos",
policyUri: "https://policy-uri/",
}),
).toEqual(dynamicClientId);
expect(JSON.parse(fetchMockJest.mock.calls[0][1]!.body as string)).not.toEqual(
expect.objectContaining({
tos_uri: "http://just.testing/tos",
policy_uri: "https://policy-uri/",
}),
);
});
}); });

View File

@@ -54,8 +54,18 @@ interface OidcRegistrationRequestBody {
export const DEVICE_CODE_SCOPE = "urn:ietf:params:oauth:grant-type:device_code"; export const DEVICE_CODE_SCOPE = "urn:ietf:params:oauth:grant-type:device_code";
// Check that URIs have a common base, as per the MSC2966 definition
const urlHasCommonBase = (base: URL, urlStr?: string): boolean => {
if (!urlStr) return false;
const url = new URL(urlStr);
if (url.protocol !== base.protocol) return false;
if (url.host !== base.host && !url.host.endsWith(`.${base.host}`)) return false;
return true;
};
/** /**
* Attempts dynamic registration against the configured registration endpoint * Attempts dynamic registration against the configured registration endpoint.
* Will ignore any URIs that do not use client_uri as a common base as per the spec.
* @param delegatedAuthConfig - Auth config from {@link discoverAndValidateOIDCIssuerWellKnown} * @param delegatedAuthConfig - Auth config from {@link discoverAndValidateOIDCIssuerWellKnown}
* @param clientMetadata - The metadata for the client which to register * @param clientMetadata - The metadata for the client which to register
* @returns Promise<string> resolved with registered clientId * @returns Promise<string> resolved with registered clientId
@@ -74,6 +84,8 @@ export const registerOidcClient = async (
throw new Error(OidcError.DynamicRegistrationNotSupported); throw new Error(OidcError.DynamicRegistrationNotSupported);
} }
const commonBase = new URL(clientMetadata.clientUri);
// https://openid.net/specs/openid-connect-registration-1_0.html // https://openid.net/specs/openid-connect-registration-1_0.html
const metadata: OidcRegistrationRequestBody = { const metadata: OidcRegistrationRequestBody = {
client_name: clientMetadata.clientName, client_name: clientMetadata.clientName,
@@ -84,11 +96,12 @@ export const registerOidcClient = async (
id_token_signed_response_alg: "RS256", id_token_signed_response_alg: "RS256",
token_endpoint_auth_method: "none", token_endpoint_auth_method: "none",
application_type: clientMetadata.applicationType, application_type: clientMetadata.applicationType,
logo_uri: clientMetadata.logoUri,
contacts: clientMetadata.contacts, contacts: clientMetadata.contacts,
policy_uri: clientMetadata.policyUri, logo_uri: urlHasCommonBase(commonBase, clientMetadata.logoUri) ? clientMetadata.logoUri : undefined,
tos_uri: clientMetadata.tosUri, policy_uri: urlHasCommonBase(commonBase, clientMetadata.policyUri) ? clientMetadata.policyUri : undefined,
tos_uri: urlHasCommonBase(commonBase, clientMetadata.tosUri) ? clientMetadata.tosUri : undefined,
}; };
const headers = { const headers = {
"Accept": "application/json", "Accept": "application/json",
"Content-Type": "application/json", "Content-Type": "application/json",