diff --git a/src/infra/push-apns-http2.test.ts b/src/infra/push-apns-http2.test.ts index 614b5e9eb80..6c96e36057f 100644 --- a/src/infra/push-apns-http2.test.ts +++ b/src/infra/push-apns-http2.test.ts @@ -123,6 +123,25 @@ describe("connectApnsHttp2Session", () => { expect(connectSpy).toHaveBeenCalledWith("https://api.push.apple.com"); }); + it("rejects APNs authorities with non-origin URL components", async () => { + const { connectApnsHttp2Session, probeApnsHttp2ReachabilityViaProxy } = + await import("./push-apns-http2.js"); + + await expect( + connectApnsHttp2Session({ + authority: "https://token@api.push.apple.com", + timeoutMs: 10_000, + }), + ).rejects.toThrow("Unsupported APNs authority"); + await expect( + probeApnsHttp2ReachabilityViaProxy({ + authority: "https://api.sandbox.push.apple.com/3/device/abc", + proxyUrl: "http://proxy.example:8080", + timeoutMs: 10_000, + }), + ).rejects.toThrow("Unsupported APNs authority"); + }); + it("uses an HTTP CONNECT tunnel when managed proxy is active", async () => { const registration = registerActiveManagedProxyUrl(new URL("http://proxy.example:8080")); const { connectApnsHttp2Session } = await import("./push-apns-http2.js"); diff --git a/src/infra/push-apns-http2.ts b/src/infra/push-apns-http2.ts index 773aadba019..32cdbe45150 100644 --- a/src/infra/push-apns-http2.ts +++ b/src/infra/push-apns-http2.ts @@ -41,6 +41,15 @@ function assertApnsAuthority(authority: string): ApnsAuthority { } catch { throw new Error(`Unsupported APNs authority: ${authority}`); } + if ( + parsed.username || + parsed.password || + parsed.pathname !== "/" || + parsed.search || + parsed.hash + ) { + throw new Error(`Unsupported APNs authority: ${authority}`); + } const port = parsed.port && parsed.port !== APNS_DEFAULT_PORT ? `:${parsed.port}` : ""; const normalized = `${parsed.protocol}//${parsed.hostname}${port}`; if (!APNS_AUTHORITIES.has(normalized)) {