allow file names with .. in it
Massimo Melina committed
Feb 7, 2022 at 18:32 UTC
6fdd8e92dab967cf097ba1864481cdcf3514d8c4
4 files changed
+12
-7
src/api.file_list.ts
+3
-3
@@ -2,7 +2,7 @@ import { getNodeName, vfs, VfsNode, walkNode } from './vfs'
2
import { ApiError, ApiHandler } from './apis'
3
import { stat } from 'fs/promises'
4
import { mapPlugins } from './plugins'
5
-import { pattern2filter } from './misc'
5
+import { dirTraversal, pattern2filter } from './misc'
6
import { FORBIDDEN } from './const'
7
import EventEmitter from 'events'
8
@@ -12,8 +12,8 @@ export const file_list:ApiHandler = async ({ path, offset, limit, search, omit,
12
return
13
if (node.forbid)
14
return new ApiError(FORBIDDEN)
15
- if (search?.includes('..'))
16
- return new ApiError(400)
15
+ if (dirTraversal(search))
16
+ return new ApiError(418)
17
if (node.default)
18
return { redirect: path }
19
offset = Number(offset)
src/middlewares.ts
+3
-2
@@ -5,7 +5,7 @@ import { BUILD_TIMESTAMP, SESSION_DURATION } from './index'
5
import Application from 'koa'
6
import { FORBIDDEN, FRONTEND_URI } from './const'
7
import { vfs } from './vfs'
8
-import { isDirectory } from './misc'
8
+import { dirTraversal, isDirectory } from './misc'
9
import { zipStreamFromFolder } from './zip'
10
import { serveFileNode } from './serveFile'
11
import { serveFrontend } from './serveFrontend'
@@ -79,7 +79,7 @@ export const frontendAndSharedFiles: Koa.Middleware = async (ctx, next) => {
79
80
export const someSecurity: Koa.Middleware = async (ctx, next) => {
81
try {
82
- if (decodeURI(ctx.path).includes('..'))
82
+ if (dirTraversal(decodeURI(ctx.path)))
83
return ctx.status = 418
84
}
85
catch {
@@ -87,3 +87,4 @@ export const someSecurity: Koa.Middleware = async (ctx, next) => {
87
}
88
return next()
89
}
90
+
src/misc.ts
+4
@@ -148,3 +148,7 @@ export function debounceAsync(cb: any, ms: number=100, ...args:any[]) {
148
finally { busy = false }
149
}
150
}
151
+
152
+export function dirTraversal(s?: string) {
153
+ return s && /(^|[/\\])\.\.($|[/\\])/.test(s)
154
+}
src/vfs.ts
+2
-2
@@ -1,7 +1,7 @@
1
import fs from 'fs/promises'
2
import { basename } from 'path'
3
import { isMatch } from 'micromatch'
4
-import { enforceFinal, isDirectory, isWindows, onlyTruthy } from './misc'
4
+import { dirTraversal, enforceFinal, isDirectory, isWindows, onlyTruthy } from './misc'
5
import Koa from 'koa'
6
import glob from 'fast-glob'
7
import _ from 'lodash'
@@ -43,7 +43,7 @@ export class Vfs {
43
async urlToNode(url: string, ctx?: Koa.Context, root?: VfsNode) : Promise<VfsNode | undefined> {
44
let run = root || this.root
45
const decoded = decodeURI(url)
46
- if (decoded.includes('..')) {
46
+ if (dirTraversal(decoded)) {
47
if (ctx)
48
ctx.status = 418
49
return