Skip to content

Commit dcec288

Browse files
Marfuenclaude
andauthored
fix(security): prevent SSRF in task-automation enterprise API calls (#3411)
Fixes CodeQL js/request-forgery (alert #116, critical). callEnterpriseApi builds `new URL(endpoint, enterpriseApiUrl)` then fetches it; getAutomationRunStatus interpolated a user-provided runId straight into the endpoint path (`/api/tasks-automations/runs/${runId}`), so a crafted runId could inject path segments into the request URL. - Encode the user value in the path (encodeURIComponent(runId)). - Add an origin allowlist guard in callEnterpriseApi: resolve the URL against the configured enterprise API base and reject anything whose origin differs, so no caller can redirect the request to another host. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 029e899 commit dcec288

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

‎apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,15 @@ async function callEnterpriseApi<T>(
5555
): Promise<T> {
5656
const { enterpriseApiUrl, enterpriseApiKey } = getEnterpriseConfig();
5757

58-
const url = new URL(endpoint, enterpriseApiUrl);
58+
const baseUrl = new URL(enterpriseApiUrl);
59+
const url = new URL(endpoint, baseUrl);
60+
61+
// SSRF guard: `endpoint` and params can carry user-derived values, so pin the
62+
// request to the configured enterprise API origin — never allow it to be
63+
// redirected to another host.
64+
if (url.origin !== baseUrl.origin) {
65+
throw new EnterpriseApiError('Invalid enterprise API endpoint', 400);
66+
}
5967

6068
if (options.params) {
6169
Object.entries(options.params).forEach(([key, value]) => {
@@ -243,8 +251,10 @@ export async function analyzeAutomationWorkflow(scriptContent: string) {
243251

244252
export const getAutomationRunStatus = async (runId: string) => {
245253
try {
246-
const result = await callEnterpriseApi(`/api/tasks-automations/runs/${runId}`, {
247-
});
254+
const result = await callEnterpriseApi(
255+
`/api/tasks-automations/runs/${encodeURIComponent(runId)}`,
256+
{},
257+
);
248258

249259
return {
250260
success: true,

0 commit comments

Comments
 (0)