Merge pull request #3645 from FreeCodeCamp/fix/form-action-attr-xss

Fix form action attr throwing xss errors
pull/3650/head
Quincy Larson 2015-10-07 18:24:38 -07:00
commit 327ddaa35e
1 changed files with 53 additions and 8 deletions

View File

@ -37,6 +37,18 @@ var common = (function() {
.replace(/fcces/gi, '</script>'); .replace(/fcces/gi, '</script>');
}; };
common.replaceFormActionAttr = function replaceFormAction(value) {
return value.replace(/<form.*?>/, function(val) {
return val.replace('action=', 'fccfaa=');
});
};
common.replaceFccfaaAttr = function replaceFccfaaAttr(value) {
return value.replace(/<form.*?>/, function(val) {
return val.replace('fccfaa=', 'action=');
});
};
return common; return common;
})(); })();
@ -44,6 +56,17 @@ var common = (function() {
common.codeUri = (function(common, encode, decode, location, history) { common.codeUri = (function(common, encode, decode, location, history) {
var replaceScriptTags = common.replaceScriptTags; var replaceScriptTags = common.replaceScriptTags;
var replaceSafeTags = common.replaceSafeTags; var replaceSafeTags = common.replaceSafeTags;
var replaceFormActionAttr = common.replaceFormActionAttr;
var replaceFccfaaAttr = common.replaceFccfaaAttr;
function encodeFcc(val) {
return replaceScriptTags(replaceFormActionAttr(val));
}
function decodeFcc(val) {
return replaceSafeTags(replaceFccfaaAttr(val));
}
var codeUri = { var codeUri = {
encode: function(code) { encode: function(code) {
return encode(code); return encode(code);
@ -72,10 +95,14 @@ common.codeUri = (function(common, encode, decode, location, history) {
}, false); }, false);
}, },
isAlive: function() { isAlive: function() {
return codeUri.isInQuery(location.search) || return codeUri.enabled &&
codeUri.isInQuery(location.search) ||
codeUri.isInQuery(location.hash); codeUri.isInQuery(location.hash);
}, },
parse: function() { parse: function() {
if (!codeUri.enabled) {
return null;
}
var query; var query;
if (location.search && codeUri.isInQuery(location.search)) { if (location.search && codeUri.isInQuery(location.search)) {
query = location.search.replace(/^\?/, ''); query = location.search.replace(/^\?/, '');
@ -85,7 +112,7 @@ common.codeUri = (function(common, encode, decode, location, history) {
null, null,
location.href.split('?')[0] location.href.split('?')[0]
); );
location.hash = '#?' + replaceScriptTags(query); location.hash = '#?' + encodeFcc(query);
} }
} else { } else {
query = location.hash.replace(/^\#\?/, ''); query = location.hash.replace(/^\#\?/, '');
@ -100,17 +127,21 @@ 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 replaceSafeTags(codeUri.decode(value || '')); return decodeFcc(codeUri.decode(value || ''));
} }
return solution; return solution;
}, null); }, null);
}, },
querify: function(solution) { querify: function(solution) {
if (!codeUri.enabled) {
return null;
}
location.hash = '?solution=' + location.hash = '?solution=' +
codeUri.encode(replaceScriptTags(solution)); codeUri.encode(encodeFcc(solution));
return solution; return solution;
} },
enabled: true
}; };
common.init.push(function() { common.init.push(function() {
@ -459,6 +490,7 @@ function workerError(error) {
var housing = $('#testSuite'); var housing = $('#testSuite');
if (display.html() !== error) { if (display.html() !== error) {
display.remove(); display.remove();
housing.prepend( housing.prepend(
'<div class="runTimeError" style="font-size: 18px;"><code>' + '<div class="runTimeError" style="font-size: 18px;"><code>' +
error.replace(/j\$/gi, '$').replace(/jdocument/gi, 'document').replace(/jjQuery/gi, 'jQuery') + error.replace(/j\$/gi, '$').replace(/jdocument/gi, 'document').replace(/jjQuery/gi, 'jQuery') +
@ -485,7 +517,10 @@ function safeHTMLRun(test) {
var codeStorage = common.codeStorage; var codeStorage = common.codeStorage;
if (common.challengeType === '0') { if (common.challengeType === '0') {
var previewFrame = document.getElementById('preview'); var previewFrame = document.getElementById('preview');
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
var preview = previewFrame.contentDocument ||
previewFrame.contentWindow.document;
if (editor.getValue().match(/\<script\>/gi) !== null) { if (editor.getValue().match(/\<script\>/gi) !== null) {
var s = editor var s = editor
.getValue() .getValue()
@ -554,9 +589,11 @@ function updatePreview() {
if (typeof prodOrDev !== 'undefined') { if (typeof prodOrDev !== 'undefined') {
var nodeEnv = prodOrDev === 'production' ? /* eslint-disable no-unused-vars */
var nodeEnv = window.prodOrDev === 'production' ?
'http://www.freecodecamp.com' : 'http://www.freecodecamp.com' :
'http://localhost:3001'; 'http://localhost:3001';
/* eslint-enable no-unused-vars */
if (common.challengeType === '0') { if (common.challengeType === '0') {
setTimeout(updatePreview, 300); setTimeout(updatePreview, 300);
@ -567,8 +604,11 @@ if (typeof prodOrDev !== 'undefined') {
* "post" methods * "post" methods
*/ */
/* eslint-disable no-unused-vars */
var testResults = []; var testResults = [];
var postSuccess = function(data) { var postSuccess = function(data) {
/* eslint-enable no-unused-vars */
var testDoc = document.createElement('div'); var testDoc = document.createElement('div');
$(testDoc).html( $(testDoc).html(
"<div class='row'><div class='col-xs-2 text-center'><i class='ion-checkmark-circled big-success-icon'></i></div><div class='col-xs-10 test-output test-vertical-center wrappable'>" + "<div class='row'><div class='col-xs-2 text-center'><i class='ion-checkmark-circled big-success-icon'></i></div><div class='col-xs-10 test-output test-vertical-center wrappable'>" +
@ -614,7 +654,9 @@ function showCompletion() {
isInitRun = false; isInitRun = false;
return; return;
} }
var time = Math.floor(Date.now()) - started;
var time = Math.floor(Date.now()) - window.started;
ga( ga(
'send', 'send',
'event', 'event',
@ -672,7 +714,10 @@ function showCompletion() {
}); });
} }
/* eslint-disable no-unused-vars */
var resetEditor = function resetEditor() { var resetEditor = function resetEditor() {
/* eslint-enable no-unused-vars */
editor.setValue(common.replaceSafeTags(common.seed)); editor.setValue(common.replaceSafeTags(common.seed));
$('#testSuite').empty(); $('#testSuite').empty();
bonfireExecute(true); bonfireExecute(true);