Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

Commit c22b78a

Browse files
committed
validate agent slug before building ingress host
1 parent a70ae4d commit c22b78a

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { describe, expect, it } from "vitest";
2+
import { agentIngressBaseUrl } from "./ingress";
3+
4+
describe("agentIngressBaseUrl", () => {
5+
it.each([
6+
{ slug: "my-agent", region: "us" as const },
7+
{ slug: "agent1", region: "us" as const },
8+
{ slug: "agent-builder", region: "eu" as const },
9+
{ slug: "a".repeat(63), region: "us" as const },
10+
])("builds a host for the valid slug $slug", ({ slug, region }) => {
11+
expect(agentIngressBaseUrl(slug, region)).toBe(
12+
`https://${slug}.agents.${region}.posthog.com`,
13+
);
14+
});
15+
16+
it("keeps the slug in the dev ingress path", () => {
17+
expect(agentIngressBaseUrl("my-agent", "dev")).toBe(
18+
"http://localhost:3030/agents/my-agent",
19+
);
20+
});
21+
22+
it.each([
23+
"evil.com/x",
24+
"evil.com#x",
25+
"evil.com?x",
26+
"a@b",
27+
"a b",
28+
"sub.domain",
29+
"-leading",
30+
"trailing-",
31+
"with_underscore",
32+
"a".repeat(64),
33+
"",
34+
])("rejects the malformed slug %j", (slug) => {
35+
expect(agentIngressBaseUrl(slug, "us")).toBeNull();
36+
expect(agentIngressBaseUrl(slug, "dev")).toBeNull();
37+
});
38+
});

packages/ui/src/features/agent-applications/utils/ingress.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import type { CloudRegion } from "@posthog/shared";
1313
*/
1414
const LOCAL_INGRESS_ORIGIN = "http://localhost:3030";
1515

16+
// Slug reaches the host below from an attacker-controllable deep link param.
17+
const AGENT_SLUG_PATTERN = /^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
18+
1619
export function resolveIngressBaseUrl(
1720
ingressBaseUrl: string | null | undefined,
1821
region: CloudRegion | null,
@@ -41,7 +44,7 @@ export function agentIngressBaseUrl(
4144
slug: string,
4245
region: CloudRegion | null,
4346
): string | null {
44-
if (!slug || !region) return null;
47+
if (!slug || !region || !AGENT_SLUG_PATTERN.test(slug)) return null;
4548
switch (region) {
4649
case "us":
4750
return `https://${slug}.agents.us.posthog.com`;

0 commit comments

Comments
 (0)