moveTorrents: get sourceBasePath and baseFileName in server

With these two properties, it is hard for third party to utilize API
to move torrents without retrieving torrent details first.

Plus, client-supplied paths and filenames can lead to arbitrary file
system access which is a security issue.

In conclusion, it doesn't make sense to let client to provide these
two properties.
This commit is contained in:
Jesse Chan
2020-09-29 17:32:11 +08:00
parent 912c66d497
commit f5f8952df9
5 changed files with 19 additions and 30 deletions
+10 -15
View File
@@ -107,15 +107,7 @@ class ClientGatewayService extends BaseService<ClientGatewayServiceEvents> {
* @param {MoveTorrentsOptions} options - An object of options...
* @return {Promise} - Resolves with the processed client response or rejects with the processed client error.
*/
async moveTorrents({
hashes,
filenames,
sourcePaths,
destination,
moveFiles,
isBasePath,
isCheckHash,
}: MoveTorrentsOptions) {
async moveTorrents({hashes, destination, moveFiles, isBasePath, isCheckHash}: MoveTorrentsOptions) {
if (this.services == null || this.services.clientRequestManager == null || this.services.torrentService == null) {
return Promise.reject();
}
@@ -152,15 +144,18 @@ class ClientGatewayService extends BaseService<ClientGatewayServiceEvents> {
});
if (moveFiles) {
sourcePaths.forEach((source, index) => {
const destinationFilePath = fileUtil.sanitizePath(path.join(resolvedPath, filenames[index]));
if (!fileUtil.isAllowedPath(destinationFilePath)) {
throw fileUtil.accessDeniedError();
hashes.forEach((hash) => {
const sourceBasePath = this.services?.torrentService.getTorrent(hash).basePath;
const baseFileName = this.services?.torrentService.getTorrent(hash).baseFilename;
if (sourceBasePath == null || baseFileName == null) {
return;
}
if (source !== destinationFilePath) {
const destinationFilePath = fileUtil.sanitizePath(path.join(resolvedPath, baseFileName));
if (sourceBasePath !== destinationFilePath) {
try {
moveSync(source, destinationFilePath, {overwrite: true});
moveSync(sourceBasePath, destinationFilePath, {overwrite: true});
} catch (err) {
console.error(`Failed to move files to ${resolvedPath}.`);
console.error(err);