fix: FileTree showing entire workspace instead of project directory
- Add debug logging to track project directory resolution - Improve path traversal security check with proper separator handling - Log entry count and first 10 entries for debugging - Fix project root validation to prevent listing workspace root The issue was that the tree was listing from the workspace root (containing gadget-code/, gadget-drone/, packages/) instead of the specific project directory. Added logging to help diagnose.
This commit is contained in:
parent
71f213d8d1
commit
2b029ebf2e
@ -724,22 +724,43 @@ class GadgetDrone extends GadgetProcess {
|
|||||||
return cb(false, { error: "No session lock active" });
|
return cb(false, { error: "No session lock active" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectRoot = WorkspaceService.getProjectDirectory(this.sessionLock.project.slug);
|
// Get the project directory for this session
|
||||||
|
const projectSlug = this.sessionLock.project.slug;
|
||||||
|
const projectRoot = WorkspaceService.getProjectDirectory(projectSlug);
|
||||||
|
|
||||||
|
this.log.debug("fileTreeRequest received", {
|
||||||
|
projectSlug,
|
||||||
|
projectRoot,
|
||||||
|
requestedPath: args.path,
|
||||||
|
});
|
||||||
|
|
||||||
if (!projectRoot) {
|
if (!projectRoot) {
|
||||||
return cb(false, { error: "Project directory not found" });
|
return cb(false, { error: `Project directory not found for slug: ${projectSlug}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no path specified, list from project root
|
||||||
|
// If path specified, resolve it relative to project root
|
||||||
const targetPath = args.path
|
const targetPath = args.path
|
||||||
? path.resolve(projectRoot, args.path)
|
? path.resolve(projectRoot, args.path)
|
||||||
: projectRoot;
|
: projectRoot;
|
||||||
|
|
||||||
// Security: Ensure path is within project root
|
// Security: Ensure resolved path is within project root
|
||||||
const normalizedTarget = path.normalize(targetPath);
|
const normalizedTarget = path.normalize(targetPath);
|
||||||
const normalizedRoot = path.normalize(projectRoot);
|
const normalizedRoot = path.normalize(projectRoot);
|
||||||
if (!normalizedTarget.startsWith(normalizedRoot)) {
|
if (!normalizedTarget.startsWith(normalizedRoot + path.sep) && normalizedTarget !== normalizedRoot) {
|
||||||
|
this.log.warn("fileTreeRequest path traversal attempt", {
|
||||||
|
targetPath: normalizedTarget,
|
||||||
|
projectRoot: normalizedRoot,
|
||||||
|
});
|
||||||
return cb(false, { error: "Access denied: path outside project root" });
|
return cb(false, { error: "Access denied: path outside project root" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.log.debug("fileTreeRequest resolved paths", {
|
||||||
|
projectRoot,
|
||||||
|
targetPath,
|
||||||
|
isRoot: targetPath === projectRoot,
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const stat = await fs.stat(targetPath);
|
const stat = await fs.stat(targetPath);
|
||||||
if (!stat.isDirectory()) {
|
if (!stat.isDirectory()) {
|
||||||
@ -754,11 +775,17 @@ class GadgetDrone extends GadgetProcess {
|
|||||||
projectRoot,
|
projectRoot,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.log.debug("fileTreeRequest completed", {
|
||||||
|
entryCount: entries.length,
|
||||||
|
entries: entries.slice(0, 10).map(e => e.name), // Log first 10 entries
|
||||||
|
});
|
||||||
|
|
||||||
cb(true, { entries });
|
cb(true, { entries });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||||
this.log.error("failed to list directory for file tree", {
|
this.log.error("failed to list directory for file tree", {
|
||||||
path: args.path,
|
path: args.path,
|
||||||
|
targetPath,
|
||||||
error: errorMessage,
|
error: errorMessage,
|
||||||
});
|
});
|
||||||
cb(false, { error: `Failed to list directory: ${errorMessage}` });
|
cb(false, { error: `Failed to list directory: ${errorMessage}` });
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user