mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-15 19:52:01 +03:00
f546a5ce1d
no issue Double slashes are treated as a HTTP calls as specified in [RFC1801](http://www.ietf.org/rfc/rfc1808.txt). Because of this behaviour the uncapitalise created an open redirect. By removing double slashes in the path we ensure open redirects cannot be created. As an example, please click the following URL: https://dev.ghost.org///Google.com/. This issue has been reported by pentesters of our product [LearningSpaces.io](http://learningspaces.io).
110 lines
3.4 KiB
JavaScript
110 lines
3.4 KiB
JavaScript
var unidecode = require('unidecode'),
|
||
_ = require('lodash'),
|
||
readCSV = require('./read-csv'),
|
||
removeOpenRedirectFromUrl = require('./remove-open-redirect-from-url'),
|
||
utils,
|
||
getRandomInt;
|
||
|
||
/**
|
||
* Return a random int, used by `utils.uid()`
|
||
*
|
||
* @param {Number} min
|
||
* @param {Number} max
|
||
* @return {Number}
|
||
* @api private
|
||
*/
|
||
getRandomInt = function (min, max) {
|
||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||
};
|
||
|
||
utils = {
|
||
/**
|
||
* Timespans in seconds and milliseconds for better readability
|
||
*/
|
||
ONE_HOUR_S: 3600,
|
||
ONE_DAY_S: 86400,
|
||
ONE_YEAR_S: 31536000,
|
||
ONE_HOUR_MS: 3600000,
|
||
ONE_DAY_MS: 86400000,
|
||
ONE_WEEK_MS: 604800000,
|
||
ONE_MONTH_MS: 2628000000,
|
||
ONE_YEAR_MS: 31536000000,
|
||
|
||
/**
|
||
* Return a unique identifier with the given `len`.
|
||
*
|
||
* utils.uid(10);
|
||
* // => "FDaS435D2z"
|
||
*
|
||
* @param {Number} len
|
||
* @return {String}
|
||
* @api private
|
||
*/
|
||
uid: function (len) {
|
||
var buf = [],
|
||
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
|
||
charlen = chars.length,
|
||
i;
|
||
|
||
for (i = 1; i < len; i = i + 1) {
|
||
buf.push(chars[getRandomInt(0, charlen - 1)]);
|
||
}
|
||
|
||
return buf.join('');
|
||
},
|
||
safeString: function (string, options) {
|
||
options = options || {};
|
||
|
||
// Handle the £ symbol separately, since it needs to be removed before the unicode conversion.
|
||
string = string.replace(/£/g, '-');
|
||
|
||
// Remove non ascii characters
|
||
string = unidecode(string);
|
||
|
||
// Replace URL reserved chars: `@:/?#[]!$&()*+,;=` as well as `\%<>|^~£"{}` and \`
|
||
string = string.replace(/(\s|\.|@|:|\/|\?|#|\[|\]|!|\$|&|\(|\)|\*|\+|,|;|=|\\|%|<|>|\||\^|~|"|\{|\}|`|–|—)/g, '-')
|
||
// Remove apostrophes
|
||
.replace(/'/g, '')
|
||
// Make the whole thing lowercase
|
||
.toLowerCase();
|
||
|
||
// We do not need to make the following changes when importing data
|
||
if (!_.has(options, 'importing') || !options.importing) {
|
||
// Convert 2 or more dashes into a single dash
|
||
string = string.replace(/-+/g, '-')
|
||
// Remove trailing dash
|
||
.replace(/-$/, '')
|
||
// Remove any dashes at the beginning
|
||
.replace(/^-/, '');
|
||
}
|
||
|
||
// Handle whitespace at the beginning or end.
|
||
string = string.trim();
|
||
|
||
return string;
|
||
},
|
||
// The token is encoded URL safe by replacing '+' with '-', '\' with '_' and removing '='
|
||
// NOTE: the token is not encoded using valid base64 anymore
|
||
encodeBase64URLsafe: function (base64String) {
|
||
return base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
||
},
|
||
// Decode url safe base64 encoding and add padding ('=')
|
||
decodeBase64URLsafe: function (base64String) {
|
||
base64String = base64String.replace(/-/g, '+').replace(/_/g, '/');
|
||
while (base64String.length % 4) {
|
||
base64String += '=';
|
||
}
|
||
return base64String;
|
||
},
|
||
redirect301: function redirect301(res, path) {
|
||
/*jslint unparam:true*/
|
||
res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
|
||
res.redirect(301, path);
|
||
},
|
||
|
||
readCSV: readCSV,
|
||
removeOpenRedirectFromUrl: removeOpenRedirectFromUrl
|
||
};
|
||
|
||
module.exports = utils;
|