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:
+3
-3
@@ -150,14 +150,14 @@ export class LambdaDriver implements LogicFunctionExecutorDriver {
|
||||
inMemoryLayerFolderPath: string;
|
||||
}) {
|
||||
await Promise.all([
|
||||
this.fileStorageService.downloadFile_v2({
|
||||
this.fileStorageService.downloadFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Dependencies,
|
||||
resourcePath: 'package.json',
|
||||
localPath: join(inMemoryLayerFolderPath, 'package.json'),
|
||||
}),
|
||||
this.fileStorageService.downloadFile_v2({
|
||||
this.fileStorageService.downloadFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Dependencies,
|
||||
@@ -368,7 +368,7 @@ export class LambdaDriver implements LogicFunctionExecutorDriver {
|
||||
|
||||
const compiledCode = (
|
||||
await streamToBuffer(
|
||||
await this.fileStorageService.readFile_v2({
|
||||
await this.fileStorageService.readFile({
|
||||
workspaceId: flatLogicFunction.workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.BuiltLogicFunction,
|
||||
|
||||
+3
-3
@@ -47,14 +47,14 @@ export class LocalDriver implements LogicFunctionExecutorDriver {
|
||||
inMemoryLayerFolderPath: string;
|
||||
}) {
|
||||
await Promise.all([
|
||||
this.fileStorageService.downloadFile_v2({
|
||||
this.fileStorageService.downloadFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Dependencies,
|
||||
resourcePath: 'package.json',
|
||||
localPath: join(inMemoryLayerFolderPath, 'package.json'),
|
||||
}),
|
||||
this.fileStorageService.downloadFile_v2({
|
||||
this.fileStorageService.downloadFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Dependencies,
|
||||
@@ -122,7 +122,7 @@ export class LocalDriver implements LogicFunctionExecutorDriver {
|
||||
|
||||
const baseFolderPath = dirname(flatLogicFunction.builtHandlerPath);
|
||||
|
||||
await this.fileStorageService.downloadFolder_v2({
|
||||
await this.fileStorageService.downloadFolder({
|
||||
workspaceId: flatLogicFunction.workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.BuiltLogicFunction,
|
||||
|
||||
+2
-2
@@ -281,13 +281,13 @@ export class LogicFunctionExecutorService
|
||||
flatApplication: FlatApplication;
|
||||
applicationUniversalIdentifier: string;
|
||||
}): Promise<boolean> {
|
||||
const packageJsonExists = await this.fileStorageService.checkFileExists_v2({
|
||||
const packageJsonExists = await this.fileStorageService.checkFileExists({
|
||||
workspaceId: flatApplication.workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Dependencies,
|
||||
resourcePath: 'package.json',
|
||||
});
|
||||
const yarnLockExists = await this.fileStorageService.checkFileExists_v2({
|
||||
const yarnLockExists = await this.fileStorageService.checkFileExists({
|
||||
workspaceId: flatApplication.workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Dependencies,
|
||||
|
||||
+8
-8
@@ -128,7 +128,7 @@ export class LogicFunctionSourceBuilderService {
|
||||
const sourceFile = sourceFiles[0];
|
||||
const builtFile = builtFiles[0];
|
||||
|
||||
await this.fileStorageService.writeFile_v2({
|
||||
await this.fileStorageService.writeFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Source,
|
||||
@@ -141,7 +141,7 @@ export class LogicFunctionSourceBuilderService {
|
||||
},
|
||||
});
|
||||
|
||||
await this.fileStorageService.writeFile_v2({
|
||||
await this.fileStorageService.writeFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.BuiltLogicFunction,
|
||||
@@ -181,7 +181,7 @@ export class LogicFunctionSourceBuilderService {
|
||||
|
||||
const baseFolderPath = getLogicFunctionBaseFolderPath(sourceHandlerPath);
|
||||
|
||||
await this.fileStorageService.uploadFolder_v2({
|
||||
await this.fileStorageService.uploadFolder({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Source,
|
||||
@@ -206,7 +206,7 @@ export class LogicFunctionSourceBuilderService {
|
||||
|
||||
const baseFolderPath = getLogicFunctionBaseFolderPath(sourceHandlerPath);
|
||||
|
||||
await this.fileStorageService.downloadFolder_v2({
|
||||
await this.fileStorageService.downloadFolder({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Source,
|
||||
@@ -231,7 +231,7 @@ export class LogicFunctionSourceBuilderService {
|
||||
|
||||
const builtFile = await fs.readFile(builtBundleFilePath, 'utf-8');
|
||||
|
||||
await this.fileStorageService.writeFile_v2({
|
||||
await this.fileStorageService.writeFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.BuiltLogicFunction,
|
||||
@@ -260,7 +260,7 @@ export class LogicFunctionSourceBuilderService {
|
||||
const baseFolderPath = getLogicFunctionBaseFolderPath(sourceHandlerPath);
|
||||
|
||||
try {
|
||||
return await this.fileStorageService.readFolder_v2({
|
||||
return await this.fileStorageService.readFolder({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Source,
|
||||
@@ -297,7 +297,7 @@ export class LogicFunctionSourceBuilderService {
|
||||
const toBuiltBaseFolderPath =
|
||||
getLogicFunctionBaseFolderPath(toBuiltHandlerPath);
|
||||
|
||||
await this.fileStorageService.copy_v2({
|
||||
await this.fileStorageService.copy({
|
||||
from: {
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
@@ -312,7 +312,7 @@ export class LogicFunctionSourceBuilderService {
|
||||
},
|
||||
});
|
||||
|
||||
await this.fileStorageService.copy_v2({
|
||||
await this.fileStorageService.copy({
|
||||
from: {
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
|
||||
Reference in New Issue
Block a user