Skip to content

Commit

Permalink
Hot fix for OpenUserJS#656
Browse files Browse the repository at this point in the history
* **NOTE** This is not the permanent solution but a compromise on existing S3 DB structure and this hot fix isn't as effecient as OpenUserJS#486 solution *(hence the term hot fix vs solution)*.
* Change `caseInsensitive` regular expression maker into `caseSensitive` with exception on username to accomodate OpenUserJS#180 without the issue in OpenUserJS#656
* This removes the future security issue with unintended hidden scripts... manual DB examination will need to happen for anyone who has done this before but can be done in time with @sizzlemctwizzle and/or @Martii... future scripts should properly be created at least.
* Noted code inconsistency with `installName` versus "more than `installName`"... this should be corrected at some point.
* Leaving `caseInsensitive` in as a potential library function in `scriptStorage`... which could probably be in libs but that's where it is currently.

Closes OpenUserJS#656
  • Loading branch information
Martii committed Jul 7, 2015
1 parent bfdfd28 commit 372c885
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 16 deletions.
10 changes: 5 additions & 5 deletions controllers/issue.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ exports.list = function (aReq, aRes, aNext) {
var installNameSlug = username + '/' + scriptname;

Script.findOne({
installName: scriptStorage.caseInsensitive(
installName: scriptStorage.caseSensitive(
installNameSlug + (type === 'libs' ? '.js' : '.user.js'))
}, function (aErr, scriptData) {
if (aErr || !scriptData) { return aNext(); }
Expand Down Expand Up @@ -171,7 +171,7 @@ exports.view = function (aReq, aRes, aNext) {
var installNameSlug = username + '/' + scriptname;

Script.findOne({
installName: scriptStorage.caseInsensitive(
installName: scriptStorage.caseSensitive(
installNameSlug + (type === 'libs' ? '.js' : '.user.js'))
}, function (aErr, aScriptData) {
if (aErr || !aScriptData) { return aNext(); }
Expand Down Expand Up @@ -270,7 +270,7 @@ exports.open = function (aReq, aRes, aNext) {
var installNameSlug = scriptStorage.getInstallName(aReq);

Script.findOne({
installName: scriptStorage.caseInsensitive(
installName: scriptStorage.caseSensitive(
installNameSlug + (type === 'libs' ? '.js' : '.user.js'))
}, function (aErr, aScriptData) {
function preRender() {
Expand Down Expand Up @@ -344,7 +344,7 @@ exports.comment = function (aReq, aRes, aNext) {
var category = type + '/' + installName + '/issues';
var authedUser = aReq.session.user;

Script.findOne({ installName: scriptStorage.caseInsensitive(installName
Script.findOne({ installName: scriptStorage.caseSensitive(installName
+ (type === 'libs' ? '.js' : '.user.js')) }, function (aErr, aScript) {
var content = aReq.body['comment-content'];

Expand Down Expand Up @@ -383,7 +383,7 @@ exports.changeStatus = function (aReq, aRes, aNext) {
var authedUser = aReq.session.user;
var changed = false;

Script.findOne({ installName: scriptStorage.caseInsensitive(installName
Script.findOne({ installName: scriptStorage.caseSensitive(installName
+ (type === 'libs' ? '.js' : '.user.js')) }, function (aErr, aScript) {

if (aErr || !aScript) { return aNext(); }
Expand Down
10 changes: 5 additions & 5 deletions controllers/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ var getScriptPageTasks = function (aOptions) {

// Show the number of open issues
var scriptOpenIssueCountQuery = Discussion.find({ category: scriptStorage
.caseInsensitive(script.issuesCategorySlug), open: {$ne: false} });
.caseSensitive(script.issuesCategorySlug, true), open: {$ne: false} });
tasks.push(countTask(scriptOpenIssueCountQuery, aOptions, 'issueCount'));

// Show the groups the script belongs to
Expand Down Expand Up @@ -311,7 +311,7 @@ exports.view = function (aReq, aRes, aNext) {

Script.findOne({
installName: scriptStorage
.caseInsensitive(installNameSlug + (isLib ? '.js' : '.user.js'))
.caseSensitive(installNameSlug + (isLib ? '.js' : '.user.js'))
}, function (aErr, aScriptData) {
function preRender() {
if (script.groups) {
Expand Down Expand Up @@ -373,7 +373,7 @@ exports.edit = function (aReq, aRes, aNext) {

Script.findOne({
installName: scriptStorage
.caseInsensitive(installNameSlug + (isLib ? '.js' : '.user.js'))
.caseSensitive(installNameSlug + (isLib ? '.js' : '.user.js'))
}, function (aErr, aScriptData) {
function preRender() {
var groupNameList = (options.script.groups || []).map(function (aGroup) {
Expand Down Expand Up @@ -467,7 +467,7 @@ exports.vote = function (aReq, aRes, aNext) {
return aRes.redirect(url);
}

Script.findOne({ installName: scriptStorage.caseInsensitive(installName) },
Script.findOne({ installName: scriptStorage.caseSensitive(installName) },
function (aErr, aScript) {
if (aErr || !aScript) { return aRes.redirect(url); }

Expand Down Expand Up @@ -532,7 +532,7 @@ exports.flag = function (aReq, aRes, aNext) {
var unflag = aReq.params.unflag;

Script.findOne({ installName: scriptStorage
.caseInsensitive(installName + (isLib ? '.js' : '.user.js')) },
.caseSensitive(installName + (isLib ? '.js' : '.user.js')) },
function (aErr, aScript) {
var fn = flagLib[unflag && unflag === 'unflag' ? 'unflag' : 'flag'];
if (aErr || !aScript) { return aNext(); }
Expand Down
64 changes: 60 additions & 4 deletions controllers/scriptStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,67 @@ function caseInsensitive(aInstallName) {
}
exports.caseInsensitive = caseInsensitive;

function caseSensitive(aInstallName, aMoreThanInstallName) {

var rExpression = null;
var rMatchExpression = aMoreThanInstallName ? /^(.*)\/(.*)\/(.*)\/(.*)$/ : /^(.*)\/(.*)$/;
var username = '';

var matches = aInstallName.match(rMatchExpression);
if (matches) {
if (aMoreThanInstallName) {

for (var char in matches[2]) {

if (matches[2][char].toLowerCase() !== matches[2][char].toUpperCase()) {
username += '[' +
matches[2][char].toLowerCase().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1") +
matches[2][char].toUpperCase().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1") + ']';
} else {
username += matches[2][char].replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}

}

rExpression = new RegExp(
'^' +
matches[1] + '/' +
username + '/' +
matches[3].replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1") + '/' +
matches[4] + '$',
''
);
} else {

for (var char in matches[1]) {

if (matches[1][char].toLowerCase() !== matches[1][char].toUpperCase()) {
username += '[' +
matches[1][char].toLowerCase().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1") +
matches[1][char].toUpperCase().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1") + ']';
} else {
username += matches[1][char].replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}
}

rExpression = new RegExp(
'^' +
username + '/' +
matches[2].replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1") + '$',
''
);
}
}

return rExpression;
}
exports.caseSensitive = caseSensitive;

exports.getSource = function (aReq, aCallback) {
var s3 = new AWS.S3();
var installName = getInstallName(aReq);

Script.findOne({ installName: caseInsensitive(installName) },
Script.findOne({ installName: caseSensitive(installName) },
function (aErr, aScript) {
var s3Object = null;

Expand Down Expand Up @@ -104,7 +160,7 @@ exports.sendScript = function (aReq, aRes, aNext) {
exports.sendMeta = function (aReq, aRes, aNext) {
var installName = getInstallName(aReq).replace(/\.meta\.js$/, '.user.js');

Script.findOne({ installName: caseInsensitive(installName) },
Script.findOne({ installName: caseSensitive(installName) },
function (aErr, aScript) {
var meta = null;
var data = null;
Expand Down Expand Up @@ -334,7 +390,7 @@ exports.storeScript = function (aUser, aMeta, aBuf, aCallback, aUpdate) {
}

// Prevent a removed script from being reuploaded
findDeadorAlive(Script, { installName: caseInsensitive(installName) }, true,
findDeadorAlive(Script, { installName: caseSensitive(installName) }, true,
function (aAlive, aScript, aRemoved) {
if (aRemoved || (!aScript && (aUpdate || collaborators))) {
return aCallback(null);
Expand Down Expand Up @@ -399,7 +455,7 @@ exports.storeScript = function (aUser, aMeta, aBuf, aCallback, aUpdate) {
};

exports.deleteScript = function (aInstallName, aCallback) {
Script.findOne({ installName: caseInsensitive(aInstallName) },
Script.findOne({ installName: caseSensitive(aInstallName) },
function (aErr, aScript) {
var s3 = new AWS.S3();
s3.deleteObject({ Bucket : bucketName, Key : aScript.installName},
Expand Down
4 changes: 2 additions & 2 deletions controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ exports.editScript = function (aReq, aRes, aNext) {

Script.findOne({
installName: scriptStorage
.caseInsensitive(installNameSlug + (isLib ? '.js' : '.user.js'))
.caseSensitive(installNameSlug + (isLib ? '.js' : '.user.js'))
}, function (aErr, aScriptData) {
//---
if (aErr || !aScriptData) { return aNext(); }
Expand All @@ -1293,7 +1293,7 @@ exports.editScript = function (aReq, aRes, aNext) {

// Show the number of open issues
var scriptOpenIssueCountQuery = Discussion.find({ category: scriptStorage
.caseInsensitive(script.issuesCategorySlug), open: {$ne: false} });
.caseSensitive(script.issuesCategorySlug, true), open: {$ne: false} });
tasks.push(countTask(scriptOpenIssueCountQuery, options, 'issueCount'));

//---
Expand Down

0 comments on commit 372c885

Please sign in to comment.