Skip to content

Commit db6328c

Browse files
committed
fix: prevent SSRF by validating S3 endpoint against allow-list in storage configuration
1 parent 63d6d4d commit db6328c

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

workflow/packages/backend/api/src/app/file/s3-helper.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@ import { AppSystemProp, exceptionHandler } from 'workflow-server-shared'
77
import { apId, FileType, ProjectId } from 'workflow-shared'
88
import { system } from '../helper/system/system'
99

10+
const ALLOWED_S3_ENDPOINTS = [
11+
"https://s3.amazonaws.com",
12+
"https://s3.us-east-1.amazonaws.com",
13+
// Add other trusted endpoints as needed
14+
];
15+
16+
function isAllowedS3Endpoint(url?: string): boolean {
17+
if (!url) return true; // Default AWS SDK endpoint if not set
18+
try {
19+
const parsed = new URL(url);
20+
return ALLOWED_S3_ENDPOINTS.some(allowed =>
21+
parsed.origin === allowed
22+
);
23+
} catch {
24+
return false;
25+
}
26+
}
27+
1028
export const s3Helper = (log: FastifyBaseLogger) => ({
1129
constructS3Key(platformId: string | undefined, projectId: ProjectId | undefined, type: FileType, fileId: string): string {
1230
const now = dayjs()
@@ -134,6 +152,11 @@ const getS3Client = () => {
134152
const useIRSA = system.getBoolean(AppSystemProp.S3_USE_IRSA)
135153
const region = system.get<string>(AppSystemProp.S3_REGION)
136154
const endpoint = system.get<string>(AppSystemProp.S3_ENDPOINT)
155+
156+
if (!isAllowedS3Endpoint(endpoint)) {
157+
throw new Error("Invalid or untrusted S3 endpoint. Only allow-listed endpoints are permitted.");
158+
}
159+
137160
const options: S3ClientConfig = {
138161
region,
139162
forcePathStyle: endpoint ? true : undefined,

0 commit comments

Comments
 (0)