Harden local file storage driver path resolution (#17783)
## Summary - Normalize all file paths with `path.resolve` instead of `join` to properly handle `..` segments in file path inputs - Add `assertPathIsWithinStorage` guard on all write, delete, move, copy, and existence-check operations - Introduce `ACCESS_DENIED` exception code with i18n-ready user-friendly message - Read path already had realpath-based validation; updated its error code to `ACCESS_DENIED` for consistency ## Test plan - [x] Typecheck passes - [x] Lint passes - [x] Manual: verify file upload/download still works with valid paths - [x] Manual: verify `../` in file paths is rejected with ACCESS_DENIED Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Etienne <etiennejouan@users.noreply.github.com>
This commit is contained in:
+2
-2
@@ -180,7 +180,7 @@ export class BackfillApplicationPackageFilesCommand extends ActiveOrSuspendedWor
|
||||
toDelete: false,
|
||||
};
|
||||
|
||||
const packageJsonFile = await this.fileStorageService.writeFile_v2({
|
||||
const packageJsonFile = await this.fileStorageService.writeFile({
|
||||
sourceFile: packageJsonContent,
|
||||
mimeType: undefined,
|
||||
fileFolder: FileFolder.Dependencies,
|
||||
@@ -190,7 +190,7 @@ export class BackfillApplicationPackageFilesCommand extends ActiveOrSuspendedWor
|
||||
settings: dependencyFileSettings,
|
||||
});
|
||||
|
||||
const yarnLockFile = await this.fileStorageService.writeFile_v2({
|
||||
const yarnLockFile = await this.fileStorageService.writeFile({
|
||||
sourceFile: layer.yarnLock,
|
||||
mimeType: undefined,
|
||||
fileFolder: FileFolder.Dependencies,
|
||||
|
||||
+4
-4
@@ -245,13 +245,13 @@ export class MigrateWorkflowCodeStepsCommand extends ActiveOrSuspendedWorkspaces
|
||||
await fs.mkdir(builtTempDir, { recursive: true });
|
||||
await fs.mkdir(sourceTempDir, { recursive: true });
|
||||
|
||||
const builtSources = await this.fileStorageService.readFolder(
|
||||
const builtSources = await this.fileStorageService.readFolderLegacy(
|
||||
oldPaths.built,
|
||||
);
|
||||
|
||||
await this.writeSourcesToLocalFolder(builtSources as Sources, builtTempDir);
|
||||
|
||||
const sourceSources = await this.fileStorageService.readFolder(
|
||||
const sourceSources = await this.fileStorageService.readFolderLegacy(
|
||||
oldPaths.source,
|
||||
);
|
||||
const flattened =
|
||||
@@ -272,7 +272,7 @@ export class MigrateWorkflowCodeStepsCommand extends ActiveOrSuspendedWorkspaces
|
||||
const builtTempDir = join(tempRoot, 'built');
|
||||
const sourceTempDir = join(tempRoot, 'source');
|
||||
|
||||
await this.fileStorageService.uploadFolder_v2({
|
||||
await this.fileStorageService.uploadFolder({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.BuiltLogicFunction,
|
||||
@@ -280,7 +280,7 @@ export class MigrateWorkflowCodeStepsCommand extends ActiveOrSuspendedWorkspaces
|
||||
localPath: builtTempDir,
|
||||
});
|
||||
|
||||
await this.fileStorageService.uploadFolder_v2({
|
||||
await this.fileStorageService.uploadFolder({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Source,
|
||||
|
||||
+11
-4
@@ -486,8 +486,12 @@ export class SeedWorkflowV1_16Command extends ActiveOrSuspendedWorkspacesMigrati
|
||||
);
|
||||
|
||||
try {
|
||||
await this.fileStorageService.delete({ folderPath: OLD_BUILT_FOLDER });
|
||||
await this.fileStorageService.delete({ folderPath: OLD_SOURCE_FOLDER });
|
||||
await this.fileStorageService.deleteLegacy({
|
||||
folderPath: OLD_BUILT_FOLDER,
|
||||
});
|
||||
await this.fileStorageService.deleteLegacy({
|
||||
folderPath: OLD_SOURCE_FOLDER,
|
||||
});
|
||||
this.logger.log(
|
||||
`Cleaned old file storage: ${OLD_BUILT_FOLDER}, ${OLD_SOURCE_FOLDER}`,
|
||||
);
|
||||
@@ -516,7 +520,10 @@ export class SeedWorkflowV1_16Command extends ActiveOrSuspendedWorkspacesMigrati
|
||||
},
|
||||
};
|
||||
|
||||
await this.fileStorageService.writeFolder(builtSources, builtFolder);
|
||||
await this.fileStorageService.writeFolder(sourceSources, sourceFolder);
|
||||
await this.fileStorageService.writeFolderLegacy(builtSources, builtFolder);
|
||||
await this.fileStorageService.writeFolderLegacy(
|
||||
sourceSources,
|
||||
sourceFolder,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user