fix: callback URL validation not validated if prompt=none

This commit is contained in:
Elias Schneider
2026-06-16 12:02:57 +02:00
parent 73bda4580a
commit 8a75774971
7 changed files with 170 additions and 18 deletions
+42
View File
@@ -673,6 +673,28 @@ test.describe('OIDC prompt parameter', () => {
expect(redirectUrl.searchParams.get('state')).toBe('nXx-6Qr-owc1SHBa');
});
test('prompt=none does not redirect login_required to an unregistered redirect_uri', async ({
page
}) => {
await page.context().clearCookies();
const oidcClient = oidcClients.nextcloud;
const urlParams = createUrlParams(oidcClient);
urlParams.set('prompt', 'none');
urlParams.set('redirect_uri', 'https://attacker.example/collect');
let attackerRedirected = false;
await page.route('https://attacker.example/**', async (route) => {
attackerRedirected = true;
await route.fulfill({ status: 200, body: 'attacker' });
});
await page.goto(`/authorize?${urlParams.toString()}`);
await expect(page.getByText(/Invalid callback URL/i)).toBeVisible();
expect(attackerRedirected).toBe(false);
expect(page.url()).not.toContain('attacker.example');
});
test('prompt=none redirects errors with response_mode=fragment', async ({ page }) => {
await page.context().clearCookies();
const oidcClient = oidcClients.nextcloud;
@@ -706,6 +728,26 @@ test.describe('OIDC prompt parameter', () => {
expect(redirectUrl.searchParams.get('state')).toBe('nXx-6Qr-owc1SHBa');
});
test('prompt=none does not redirect consent_required to an unregistered redirect_uri', async ({
page
}) => {
const oidcClient = oidcClients.immich;
const urlParams = createUrlParams(oidcClient);
urlParams.set('prompt', 'none');
urlParams.set('redirect_uri', 'https://attacker.example/collect');
let attackerRedirected = false;
await page.route('https://attacker.example/**', async (route) => {
attackerRedirected = true;
await route.fulfill({ status: 200, body: 'attacker' });
});
await page.goto(`/authorize?${urlParams.toString()}`);
await expect(page.getByText(/Invalid callback URL/i)).toBeVisible();
expect(attackerRedirected).toBe(false);
});
test('prompt=none succeeds when user is authenticated and authorized', async ({ page }) => {
const oidcClient = oidcClients.nextcloud;
const urlParams = createUrlParams(oidcClient);