validate backup folder and prefix
This commit is contained in:
@@ -32,6 +32,7 @@ var assert = require('assert'),
|
||||
EventEmitter = require('events'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
paths = require('../paths.js'),
|
||||
prettyBytes = require('pretty-bytes'),
|
||||
readdirp = require('readdirp'),
|
||||
safe = require('safetydance'),
|
||||
@@ -225,18 +226,42 @@ function removeDir(apiConfig, pathPrefix) {
|
||||
return events;
|
||||
}
|
||||
|
||||
function validateBackupTarget(folder) {
|
||||
assert.strictEqual(typeof folder, 'string');
|
||||
|
||||
if (path.normalize(folder) !== folder) return new BoxError(BoxError.BAD_FIELD, 'backupFolder must contain a normalized relative path', { field: 'backupFolder' });
|
||||
if (!path.isAbsolute(folder)) return new BoxError(BoxError.BAD_FIELD, 'backupFolder must be an absolute path', { field: 'backupFolder' });
|
||||
|
||||
if (folder === '/') return new BoxError(BoxError.BAD_FIELD, 'backupFolder cannot be /', { field: 'backupFolder' });
|
||||
|
||||
if (!folder.endsWith('/')) folder = folder + '/'; // ensure trailing slash for the prefix matching to work
|
||||
const PROTECTED_PREFIXES = [ '/boot/', '/usr/', '/bin/', '/lib/', '/root/', '/var/lib/', paths.baseDir() ];
|
||||
|
||||
if (PROTECTED_PREFIXES.some(p => folder.startsWith(p))) return new BoxError(BoxError.BAD_FIELD, 'backupFolder path is protected', { field: 'backupFolder' });
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function testConfig(apiConfig, callback) {
|
||||
assert.strictEqual(typeof apiConfig, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
if (apiConfig.provider === PROVIDER_FILESYSTEM) {
|
||||
if (!apiConfig.backupFolder || typeof apiConfig.backupFolder !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'backupFolder must be non-empty string', { field: 'backupFolder' }));
|
||||
let error = validateBackupTarget(apiConfig.backupFolder);
|
||||
if (error) return callback(error);
|
||||
|
||||
if ('externalDisk' in apiConfig && typeof apiConfig.externalDisk !== 'boolean') return callback(new BoxError(BoxError.BAD_FIELD, 'externalDisk must be boolean', { field: 'externalDisk' }));
|
||||
}
|
||||
|
||||
if (apiConfig.provider === PROVIDER_SSHFS || apiConfig.provider === PROVIDER_CIFS || apiConfig.provider === PROVIDER_NFS) {
|
||||
if (!apiConfig.mountPoint || typeof apiConfig.mountPoint !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'mountPoint must be non-empty string', { field: 'mountPoint' }));
|
||||
let error = validateBackupTarget(apiConfig.mountPoint);
|
||||
if (error) return callback(error);
|
||||
|
||||
if (typeof apiConfig.prefix !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'prefix must be a string', { field: 'prefix' }));
|
||||
if (path.isAbsolute(apiConfig.prefix)) return new BoxError(BoxError.BAD_FIELD, 'prefix must be a relative path', { field: 'backupFolder' });
|
||||
if (path.normalize(apiConfig.prefix) !== apiConfig.prefix) return callback(new BoxError(BoxError.BAD_FIELD, 'prefix must contain a normalized relative path', { field: 'prefix' }));
|
||||
|
||||
const mounts = safe.fs.readFileSync('/proc/mounts', 'utf8');
|
||||
const mountInfo = mounts.split('\n').filter(function (l) { return l.indexOf(apiConfig.mountPoint) !== -1; })[0];
|
||||
|
||||
Reference in New Issue
Block a user