Skip to content

Commit 6ef1ade

Browse files
committed
chore: path validation before policy check
1 parent 1c102a5 commit 6ef1ade

File tree

1 file changed

+21
-38
lines changed

1 file changed

+21
-38
lines changed

packages/appkit/src/plugins/files/plugin.ts

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,12 @@ export class FilesPlugin extends Plugin {
9999
}));
100100
}
101101

102-
/** Whether a volume has a policy attached. */
103-
private _hasPolicy(volumeKey: string): boolean {
104-
return typeof this.volumeConfigs[volumeKey]?.policy === "function";
105-
}
106-
107102
/**
108103
* Extract user identity from the request.
109104
* Falls back to `getCurrentUserId()` in development mode.
110105
*/
111106
private _extractUser(req: express.Request): FilePolicyUser {
112-
const userId = req.header("x-forwarded-user");
107+
const userId = req.header("x-forwarded-user")?.trim();
113108
if (userId) return { id: userId };
114109
if (process.env.NODE_ENV === "development") {
115110
logger.warn(
@@ -168,8 +163,6 @@ export class FilesPlugin extends Plugin {
168163
path: string,
169164
resourceOverrides?: Partial<FileResource>,
170165
): Promise<boolean> {
171-
if (!this._hasPolicy(volumeKey)) return true;
172-
173166
let user: FilePolicyUser;
174167
try {
175168
user = this._extractUser(req);
@@ -561,14 +554,14 @@ export class FilesPlugin extends Plugin {
561554
): Promise<void> {
562555
const path = req.query.path as string;
563556

564-
if (!(await this._enforcePolicy(req, res, volumeKey, "read", path))) return;
565-
566557
const valid = this._isValidPath(path);
567558
if (valid !== true) {
568559
res.status(400).json({ error: valid, plugin: this.name });
569560
return;
570561
}
571562

563+
if (!(await this._enforcePolicy(req, res, volumeKey, "read", path))) return;
564+
572565
try {
573566
const result = await this.execute(
574567
async () => connector.read(getWorkspaceClient(), path),
@@ -624,15 +617,15 @@ export class FilesPlugin extends Plugin {
624617
): Promise<void> {
625618
const path = req.query.path as string;
626619

627-
if (!(await this._enforcePolicy(req, res, volumeKey, opts.mode, path)))
628-
return;
629-
630620
const valid = this._isValidPath(path);
631621
if (valid !== true) {
632622
res.status(400).json({ error: valid, plugin: this.name });
633623
return;
634624
}
635625

626+
if (!(await this._enforcePolicy(req, res, volumeKey, opts.mode, path)))
627+
return;
628+
636629
const label = opts.mode === "download" ? "Download" : "Raw fetch";
637630
const volumeCfg = this.volumeConfigs[volumeKey];
638631

@@ -704,15 +697,15 @@ export class FilesPlugin extends Plugin {
704697
): Promise<void> {
705698
const path = req.query.path as string;
706699

707-
if (!(await this._enforcePolicy(req, res, volumeKey, "exists", path)))
708-
return;
709-
710700
const valid = this._isValidPath(path);
711701
if (valid !== true) {
712702
res.status(400).json({ error: valid, plugin: this.name });
713703
return;
714704
}
715705

706+
if (!(await this._enforcePolicy(req, res, volumeKey, "exists", path)))
707+
return;
708+
716709
try {
717710
const result = await this.execute(
718711
async () => connector.exists(getWorkspaceClient(), path),
@@ -740,15 +733,15 @@ export class FilesPlugin extends Plugin {
740733
): Promise<void> {
741734
const path = req.query.path as string;
742735

743-
if (!(await this._enforcePolicy(req, res, volumeKey, "metadata", path)))
744-
return;
745-
746736
const valid = this._isValidPath(path);
747737
if (valid !== true) {
748738
res.status(400).json({ error: valid, plugin: this.name });
749739
return;
750740
}
751741

742+
if (!(await this._enforcePolicy(req, res, volumeKey, "metadata", path)))
743+
return;
744+
752745
try {
753746
const result = await this.execute(
754747
async () => connector.metadata(getWorkspaceClient(), path),
@@ -776,15 +769,15 @@ export class FilesPlugin extends Plugin {
776769
): Promise<void> {
777770
const path = req.query.path as string;
778771

779-
if (!(await this._enforcePolicy(req, res, volumeKey, "preview", path)))
780-
return;
781-
782772
const valid = this._isValidPath(path);
783773
if (valid !== true) {
784774
res.status(400).json({ error: valid, plugin: this.name });
785775
return;
786776
}
787777

778+
if (!(await this._enforcePolicy(req, res, volumeKey, "preview", path)))
779+
return;
780+
788781
try {
789782
const result = await this.execute(
790783
async () => connector.preview(getWorkspaceClient(), path),
@@ -920,17 +913,15 @@ export class FilesPlugin extends Plugin {
920913
const dirPath =
921914
typeof req.body?.path === "string" ? req.body.path : undefined;
922915

923-
if (
924-
!(await this._enforcePolicy(req, res, volumeKey, "mkdir", dirPath ?? "/"))
925-
)
926-
return;
927-
928916
const valid = this._isValidPath(dirPath);
929917
if (valid !== true) {
930918
res.status(400).json({ error: valid, plugin: this.name });
931919
return;
932920
}
933921

922+
if (!(await this._enforcePolicy(req, res, volumeKey, "mkdir", dirPath)))
923+
return;
924+
934925
try {
935926
const settings: PluginExecutionSettings = {
936927
default: FILES_WRITE_DEFAULTS,
@@ -963,24 +954,16 @@ export class FilesPlugin extends Plugin {
963954
): Promise<void> {
964955
const rawPath = req.query.path as string | undefined;
965956

966-
if (
967-
!(await this._enforcePolicy(
968-
req,
969-
res,
970-
volumeKey,
971-
"delete",
972-
rawPath ?? "/",
973-
))
974-
)
975-
return;
976-
977957
const valid = this._isValidPath(rawPath);
978958
if (valid !== true) {
979959
res.status(400).json({ error: valid, plugin: this.name });
980960
return;
981961
}
982962
const path = rawPath as string;
983963

964+
if (!(await this._enforcePolicy(req, res, volumeKey, "delete", path)))
965+
return;
966+
984967
try {
985968
const settings: PluginExecutionSettings = {
986969
default: FILES_WRITE_DEFAULTS,

0 commit comments

Comments
 (0)