Fix replace script tags in URL

Replace script tags in URL with fcc tags.
This prevents some xss bugs blocking code from running
in the iFrame.
This commit is contained in:
Berkeley Martinez
2015-10-06 16:39:15 -07:00
parent e6afda62c7
commit 33e8f35bbf
3 changed files with 56 additions and 34 deletions

View File

@ -1,31 +1,49 @@
// common namespace var common = (function() {
// all classes should be stored here // common namespace
var common = common || { // all classes should be stored here
// init is an array of functions that are var common = window.common || {
// called at the beginning of dom ready // init is an array of functions that are
init: [] // called at the beginning of dom ready
}; init: []
};
common.challengeName = common.challengeName || window.challenge_Name ? common.challengeName = common.challengeName || window.challenge_Name ?
window.challenge_Name : window.challenge_Name :
''; '';
common.challengeType = common.challengeType || window.challengeType ? common.challengeType = common.challengeType || window.challengeType ?
window.challengeType : window.challengeType :
0; 0;
common.challengeId = common.challengeId || window.challenge_Id; common.challengeId = common.challengeId || window.challenge_Id;
common.challengeSeed = common.challengeSeed || window.challengeSeed ? common.challengeSeed = common.challengeSeed || window.challengeSeed ?
window.challengeSeed : window.challengeSeed :
[]; [];
common.seed = common.challengeSeed.reduce(function(seed, line) { common.seed = common.challengeSeed.reduce(function(seed, line) {
return seed + line + '\n'; return seed + line + '\n';
}, ''); }, '');
common.replaceScriptTags = function replaceScriptTags(value) {
return value
.replace(/<script>/gi, 'fccss')
.replace(/<\/script>/gi, 'fcces');
};
common.replaceSafeTags = function replaceSafeTags(value) {
return value
.replace(/fccss/gi, '<script>')
.replace(/fcces/gi, '</script>');
};
return common;
})();
// store code in the URL // store code in the URL
common.codeUri = (function(common, encode, decode, location, history) { common.codeUri = (function(common, encode, decode, location, history) {
var replaceScriptTags = common.replaceScriptTags;
var replaceSafeTags = common.replaceSafeTags;
var codeUri = { var codeUri = {
encode: function(code) { encode: function(code) {
return encode(code); return encode(code);
@ -67,7 +85,7 @@ common.codeUri = (function(common, encode, decode, location, history) {
null, null,
location.href.split('?')[0] location.href.split('?')[0]
); );
location.hash = '#?' + query; location.hash = '#?' + replaceScriptTags(query);
} }
} else { } else {
query = location.hash.replace(/^\#\?/, ''); query = location.hash.replace(/^\#\?/, '');
@ -82,13 +100,15 @@ common.codeUri = (function(common, encode, decode, location, history) {
var key = param.split('=')[0]; var key = param.split('=')[0];
var value = param.split('=')[1]; var value = param.split('=')[1];
if (key === 'solution') { if (key === 'solution') {
return codeUri.decode(value); return replaceSafeTags(codeUri.decode(value || ''));
} }
return solution; return solution;
}, null); }, null);
}, },
querify: function(solution) { querify: function(solution) {
location.hash = '?solution=' + codeUri.encode(solution); location.hash = '?solution=' +
codeUri.encode(replaceScriptTags(solution));
return solution; return solution;
} }
}; };
@ -306,12 +326,6 @@ var sandBox = (function(jailed, codeOutput) {
return sandBox; return sandBox;
}(window.jailed, common.codeOutput)); }(window.jailed, common.codeOutput));
function replaceSafeTags(value) {
return value
.replace(/fccss/gi, '<script>')
.replace(/fcces/gi, '</script>');
}
var BDDregex = new RegExp( var BDDregex = new RegExp(
'(expect(\\s+)?\\(.*\\;)|' + '(expect(\\s+)?\\(.*\\;)|' +
'(assert(\\s+)?\\(.*\\;)|' + '(assert(\\s+)?\\(.*\\;)|' +
@ -416,7 +430,7 @@ var editor = (function(CodeMirror, emmetCodeMirror, common) {
common.seed; common.seed;
} }
editor.setValue(replaceSafeTags(editorValue)); editor.setValue(common.replaceSafeTags(editorValue));
editor.refresh(); editor.refresh();
}); });
@ -659,7 +673,7 @@ function showCompletion() {
} }
var resetEditor = function resetEditor() { var resetEditor = function resetEditor() {
editor.setValue(replaceSafeTags(common.seed)); editor.setValue(common.replaceSafeTags(common.seed));
$('#testSuite').empty(); $('#testSuite').empty();
bonfireExecute(true); bonfireExecute(true);
common.codeStorage.updateStorage(); common.codeStorage.updateStorage();

View File

@ -11,6 +11,12 @@ const debug = debugFactory('freecc:boot:user');
const daysBetween = 1.5; const daysBetween = 1.5;
const sendNonUserToMap = ifNoUserRedirectTo('/map'); const sendNonUserToMap = ifNoUserRedirectTo('/map');
function replaceScriptTags(value) {
return value
.replace(/<script>/gi, 'fccss')
.replace(/<\/script>/gi, 'fcces');
}
function calcCurrentStreak(cals) { function calcCurrentStreak(cals) {
const revCals = cals.concat([Date.now()]).slice().reverse(); const revCals = cals.concat([Date.now()]).slice().reverse();
let streakBroken = false; let streakBroken = false;
@ -239,7 +245,9 @@ module.exports = function(app) {
moment, moment,
longestStreak: profileUser.longestStreak, longestStreak: profileUser.longestStreak,
currentStreak: profileUser.currentStreak currentStreak: profileUser.currentStreak,
replaceScriptTags
}); });
} }
); );

View File

@ -131,7 +131,7 @@ block content
td.col-xs-4= bonfire.name td.col-xs-4= bonfire.name
td.col-xs-2= moment(bonfire.completedDate, 'x').format("MMM DD, YYYY") td.col-xs-2= moment(bonfire.completedDate, 'x').format("MMM DD, YYYY")
td.col-xs-6 td.col-xs-6
a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(bonfire.solution), target='_blank') View my solution a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(replaceScriptTags(bonfire.solution)), target='_blank') View my solution
if (waypoints.length > 0) if (waypoints.length > 0)
.col-sm-12 .col-sm-12
table.table.table-striped table.table.table-striped
@ -146,7 +146,7 @@ block content
td.col-xs-2= moment(challenge.completedDate, 'x').format("MMM DD, YYYY") td.col-xs-2= moment(challenge.completedDate, 'x').format("MMM DD, YYYY")
td.col-xs-6 td.col-xs-6
if (challenge.solution) if (challenge.solution)
a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(challenge.solution), target='_blank') View my solution a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(replaceScriptTags(challenge.solution)), target='_blank') View my solution
else else
a(href='/challenges/' + challenge.name) View this challenge a(href='/challenges/' + challenge.name) View this challenge