-
-
Notifications
You must be signed in to change notification settings - Fork 0
Add express server to studio mode, add Flush method
#810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
express server to studio mode, add Flush method
local devenv
| const fs = fsExtra.default || fsExtra; | ||
|
|
||
| try { | ||
| if (await fs.pathExists(outputPath)) { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the issue, we need to validate and sanitize the data.outputPath before using it to construct file paths. The best approach is to ensure that the resolved path is contained within a safe root directory. This involves:
- Normalizing the path using
path.resolveto remove any..segments. - Using
fs.realpathSyncto resolve symbolic links. - Verifying that the normalized path starts with the intended root directory.
Additionally, we can use an allowlist or sanitize the filename if only simple filenames are expected.
Changes are required in packages/express/src/client-requests/pack-requests.ts to validate data.outputPath before constructing outputPath.
-
Copy modified line R40 -
Copy modified line R42 -
Copy modified line R44 -
Copy modified lines R46-R56 -
Copy modified lines R58-R59
| @@ -39,14 +39,22 @@ | ||
| if (data.outputPath) { | ||
| // If output path is provided, check if it's absolute or relative | ||
| // Validate and sanitize the provided output path | ||
| const pathModule = await import('path'); | ||
| const fsModule = await import('fs'); | ||
| const path = pathModule.default || pathModule; | ||
| const fs = fsModule.default || fsModule; | ||
|
|
||
| if (path.isAbsolute(data.outputPath)) { | ||
| // Use absolute path as-is | ||
| outputPath = data.outputPath; | ||
| } else { | ||
| // Relative path - combine with project path in studio mode | ||
| const projectPath = process.env.PROJECT_PATH || process.cwd(); | ||
| outputPath = path.join(projectPath, data.outputPath); | ||
| const safeRoot = ENV.NODE_ENV === 'studio' ? | ||
| '/tmp/skuilder-studio-output' : | ||
| process.cwd(); | ||
|
|
||
| // Resolve the path relative to the safe root | ||
| const resolvedPath = path.resolve(safeRoot, data.outputPath); | ||
|
|
||
| // Ensure the resolved path is within the safe root directory | ||
| const realPath = fs.realpathSync(resolvedPath); | ||
| if (!realPath.startsWith(safeRoot)) { | ||
| throw new Error(`Invalid output path: ${data.outputPath}`); | ||
| } | ||
|
|
||
| outputPath = realPath; | ||
| } else { |
| try { | ||
| if (await fs.pathExists(outputPath)) { | ||
| logger.info(`Removing existing directory: ${outputPath}`); | ||
| await fs.remove(outputPath); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the issue, we need to validate and sanitize the outputPath before using it. The best approach is to normalize the path using path.resolve and ensure it remains within a designated root directory. This prevents directory traversal attacks and ensures the path is safe to use. If the path is invalid or outside the root directory, the operation should be aborted with an appropriate error response.
Changes required:
- Introduce a designated root directory for file operations (e.g.,
/tmp/skuilder-output). - Normalize
outputPathusingpath.resolve. - Check that the normalized path starts with the root directory.
- Reject paths that fail validation with an appropriate error message.
-
Copy modified lines R39-R42 -
Copy modified lines R44-R45 -
Copy modified lines R47-R49 -
Copy modified line R51 -
Copy modified lines R54-R56
| @@ -38,20 +38,20 @@ | ||
|
|
||
| const pathModule = await import('path'); | ||
| const path = pathModule.default || pathModule; | ||
| const ROOT_DIR = '/tmp/skuilder-output'; // Define a safe root directory | ||
|
|
||
| if (data.outputPath) { | ||
| // If output path is provided, check if it's absolute or relative | ||
| const pathModule = await import('path'); | ||
| const path = pathModule.default || pathModule; | ||
| // Normalize the provided path | ||
| const resolvedPath = path.resolve(ROOT_DIR, data.outputPath); | ||
|
|
||
| if (path.isAbsolute(data.outputPath)) { | ||
| // Use absolute path as-is | ||
| outputPath = data.outputPath; | ||
| } else { | ||
| // Relative path - combine with project path in studio mode | ||
| const projectPath = process.env.PROJECT_PATH || process.cwd(); | ||
| outputPath = path.join(projectPath, data.outputPath); | ||
| // Ensure the resolved path is within the root directory | ||
| if (!resolvedPath.startsWith(ROOT_DIR)) { | ||
| throw new Error(`Invalid outputPath: ${data.outputPath}. Path must be within ${ROOT_DIR}.`); | ||
| } | ||
| outputPath = resolvedPath; | ||
| } else { | ||
| // No output path provided - use default | ||
| outputPath = ENV.NODE_ENV === 'studio' ? | ||
| '/tmp/skuilder-studio-output' : | ||
| process.cwd(); | ||
| outputPath = path.resolve(ROOT_DIR, ENV.NODE_ENV === 'studio' ? | ||
| 'skuilder-studio-output' : | ||
| 'default-output'); | ||
| } |
Toward #791
PR
packages/expressbackend to the cli studio mode, enabling attachment processing hookspackcommand to express server, and exposes it as a server_requestPending testing & documentation updates, this probably achieves basic goals of #791.
expressapp in cli