mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 10:39:32 +01:00
fix(html-view): re-check workspace confinement on every served request
The serving route checked the blocklist per request but not attachmentConfineToWorkspace, while the attachment serve path (file-routes.ts) re-checks it every time. A capability minted for a folder outside the workspace before an admin turned confinement on kept serving that folder for the rest of its TTL. The capability record now says whether its folder was admitted from outside the workspace, and the serving route refuses such a record while confinement is on. The flag is part of the reuse key, so an out-of-workspace mint never picks up a capability recorded as in-workspace for the same folder. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
fe50ad0be3
commit
876dbca074
4 files changed
+40
-8
No files matched your search
@@ -201,7 +201,7 @@ export function registerHtmlViewRoutes(app: FastifyInstance, ctx: SessionPort):
|
||||
return;
|
||||
}
|
||||
|
||||
const cap = htmlViewCapabilities.mint(dirname(resolvedPath), ownerFor(req));
|
||||
const cap = htmlViewCapabilities.mint(dirname(resolvedPath), ownerFor(req), !inWorkspace);
|
||||
return {
|
||||
success: true,
|
||||
data: { url: `${HTML_VIEW_PREFIX}/${cap}/${encodeURIComponent(basename(resolvedPath))}` },
|
||||
@@ -238,6 +238,10 @@ export function registerHtmlViewRoutes(app: FastifyInstance, ctx: SessionPort):
|
||||
if (!contentType) return notFound();
|
||||
const guard = await loadAttachmentGuardConfig();
|
||||
if (isBlockedAttachmentPath(resolvedPath, guard.blockedTrees)) return notFound();
|
||||
// Re-checked per request, like the attachment serve path (file-routes.ts): a
|
||||
// page minted from outside the workspace before an admin switched confinement
|
||||
// on stops serving once it is on, instead of living out its capability.
|
||||
if (record.outsideWorkspace && guard.confineToWorkspace) return notFound();
|
||||
|
||||
const stat = await fs.stat(resolvedPath).catch(() => null);
|
||||
if (!stat?.isFile() || exceedsDownloadLimit(stat.size)) return notFound();
|
||||
|
||||
Reference in new issue
Block a user