From d65451bfbbac50097dce7b7907da73784981791b Mon Sep 17 00:00:00 2001 From: Jesse Chan Date: Thu, 27 Aug 2020 11:22:57 +0800 Subject: [PATCH] server: add a function to sanitize paths --- server/models/ClientRequest.js | 1 - server/models/Filesystem.js | 2 +- server/models/client.js | 6 +++--- server/util/fileUtil.js | 8 ++++++++ 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/server/models/ClientRequest.js b/server/models/ClientRequest.js index f30af58d..3a8253b4 100644 --- a/server/models/ClientRequest.js +++ b/server/models/ClientRequest.js @@ -1,7 +1,6 @@ /** * This file is deprecated in favor of clientGatewayService. */ -const fs = require('fs'); const mv = require('mv'); const path = require('path'); const util = require('util'); diff --git a/server/models/Filesystem.js b/server/models/Filesystem.js index 41221ae1..4b3781ae 100644 --- a/server/models/Filesystem.js +++ b/server/models/Filesystem.js @@ -7,7 +7,7 @@ const fileUtil = require('../util/fileUtil'); const getDirectoryList = (options, callback) => { const sourcePath = (options.path || '/').replace(/^~/, os.homedir()); - const resolvedPath = path.resolve(sourcePath); + const resolvedPath = fileUtil.sanitizePath(sourcePath); if (!fileUtil.isAllowedPath(resolvedPath)) { callback(null, fileUtil.accessDeniedError()); return; diff --git a/server/models/client.js b/server/models/client.js index 9bb5820b..50ed97a5 100644 --- a/server/models/client.js +++ b/server/models/client.js @@ -24,7 +24,7 @@ const client = { tags = tags.split(','); } - const resolvedPath = path.resolve(destinationPath); + const resolvedPath = fileUtil.sanitizePath(destinationPath); if (!fileUtil.isAllowedPath(resolvedPath)) { callback(null, fileUtil.accessDeniedError()); return; @@ -65,7 +65,7 @@ const client = { addUrls(user, services, data, callback) { const {urls, destination, isBasePath, start, tags} = data; const request = new ClientRequest(user, services); - const resolvedPath = path.resolve(destination); + const resolvedPath = fileUtil.sanitizePath(destination); if (!fileUtil.isAllowedPath(resolvedPath)) { callback(null, fileUtil.accessDeniedError()); return; @@ -242,7 +242,7 @@ const client = { const {isBasePath, hashes, filenames, moveFiles, sourcePaths, isCheckHash} = data; const mainRequest = new ClientRequest(user, services); - const resolvedPath = path.resolve(destinationPath); + const resolvedPath = fileUtil.sanitizePath(destinationPath); if (!fileUtil.isAllowedPath(resolvedPath)) { callback(null, fileUtil.accessDeniedError()); return; diff --git a/server/util/fileUtil.js b/server/util/fileUtil.js index 46a0bdff..4dacb720 100644 --- a/server/util/fileUtil.js +++ b/server/util/fileUtil.js @@ -1,4 +1,5 @@ const fs = require('fs'); +const path = require('path'); const config = require('../../config'); @@ -24,6 +25,12 @@ const isAllowedPath = (resolvedPath) => { }); }; +const sanitizePath = (input) => { + // eslint-disable-next-line no-control-regex + const controlRe = /[\x00-\x1f\x80-\x9f]/g; + return path.resolve(input).replace(controlRe, ''); +}; + const accessDeniedError = () => { const error = new Error(); error.code = 'EACCES'; @@ -33,6 +40,7 @@ const accessDeniedError = () => { const fileUtil = { createDirectory, isAllowedPath, + sanitizePath, accessDeniedError, };