diff --git a/includes/libraries/csrfp/js/csrfprotector.js b/includes/libraries/csrfp/js/csrfprotector.js index 7616d92d2..395293ca4 100644 --- a/includes/libraries/csrfp/js/csrfprotector.js +++ b/includes/libraries/csrfp/js/csrfprotector.js @@ -11,6 +11,9 @@ * ================================================================= */ +var CSRFP_FIELD_TOKEN_NAME = 'csrfp_hidden_data_token'; +var CSRFP_FIELD_URLS = 'csrfp_hidden_data_urls'; + var CSRFP = { CSRFP_TOKEN: 'c42f1a870f5a58088dbfaea2f9788d9f967ecfa64251de294d', /** @@ -140,6 +143,14 @@ var CSRFP = { * @return void */ _init: function() { + CSRFP.CSRFP_TOKEN = document.getElementById(CSRFP_FIELD_TOKEN_NAME).value; + try { + CSRFP.checkForUrls = JSON.parse(document.getElementById(CSRFP_FIELD_URLS).value); + } catch (err) { + console.error(err); + console.error('[ERROR] [CSRF Protector] unable to parse blacklisted url fields.'); + } + //convert these rules received from php lib to regex objects for (var i = 0; i < CSRFP.checkForUrls.length; i++) { CSRFP.checkForUrls[i] = CSRFP.checkForUrls[i].replace(/\*/g, '(.*)') @@ -247,14 +258,16 @@ function csrfprotector_init() { */ function new_send(data) { if (this.method.toLowerCase() === 'post') { - - if (data !== "") { - data += "&"; + if (data !== null && typeof data === 'object') { + data.append(CSRFP.CSRFP_TOKEN, CSRFP._getAuthKey()); } else { - data = ""; + if (typeof data != "undefined") { + data += "&"; + } else { + data = ""; + } + data += CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey(); } - - data += CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey(); } return this.old_send(data); } @@ -276,39 +289,47 @@ function csrfprotector_init() { // Rewrite existing urls ( Attach CSRF token ) // Rules: // Rewrite those urls which matches the regex sent by Server - // Ingore cross origin urls & internal links (one with hashtags) + // Ignore cross origin urls & internal links (one with hashtags) // Append the token to those url already containig GET query parameter(s) // Add the token to those which does not contain GET query parameter(s) //================================================================== for (var i = 0; i < document.links.length; i++) { - document.links[i].addEventListener("mousedown", function(event) { - var urlDisect = event.target.href.split('#'); - var url = urlDisect[0]; - var hash = urlDisect[1]; - - if(CSRFP._getDomain(url).indexOf(document.domain) === -1 - || CSRFP._isValidGetRequest(url)) { - //cross origin or not to be protected by rules -- ignore - return; - } - - if (url.indexOf('?') !== -1) { - if(url.indexOf(CSRFP.CSRFP_TOKEN) === -1) { - url += "&" +CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey(); - } else { - url = url.replace(new RegExp(CSRFP.CSRFP_TOKEN +"=.*?(&|$)", 'g'), - CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey() + "$1"); - } - } else { - url += "?" +CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey(); - } - - event.target.href = url; - if (typeof hash !== 'undefined') { - event.target.href += '#' +hash; - } - }); + document.links[i].addEventListener("mousedown", function(event) { + var href = event.target.href; + if(typeof href === "string") + { + var urlDisect = href.split('#'); + var url = urlDisect[0]; + var hash = urlDisect[1]; + + if(CSRFP._getDomain(url).indexOf(document.domain) === -1 + || CSRFP._isValidGetRequest(url)) { + //cross origin or not to be protected by rules -- ignore + return; + } + + if (url.indexOf('?') !== -1) { + if(url.indexOf(CSRFP.CSRFP_TOKEN) === -1) { + url += "&" +CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey(); + } else { + url = url.replace(new RegExp(CSRFP.CSRFP_TOKEN +"=.*?(&|$)", 'g'), + CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey() + "$1"); + } + } else { + url += "?" +CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey(); + } + + event.target.href = url; + if (typeof hash !== 'undefined') { + event.target.href += '#' +hash; + } + } + }); } -} \ No newline at end of file +} + +window.addEventListener("DOMContentLoaded", function() { + csrfprotector_init(); +}, false); diff --git a/includes/libraries/csrfp/libs/csrf/csrfpJsFileBase.php b/includes/libraries/csrfp/libs/csrf/csrfpJsFileBase.php deleted file mode 100644 index 406490e82..000000000 --- a/includes/libraries/csrfp/libs/csrf/csrfpJsFileBase.php +++ /dev/null @@ -1,314 +0,0 @@ -/** - * ================================================================= - * Javascript code for OWASP CSRF Protector - * Task it does: Fetch csrftoken from cookie, and attach it to every - * POST request - * Allowed GET url - * -- XHR - * -- Static Forms - * -- URLS (GET only) - * -- dynamic forms - * ================================================================= - */ - -var CSRFP = { - CSRFP_TOKEN: '$$tokenName$$', - /** - * Array of patterns of url, for which csrftoken need to be added - * In case of GET request also, provided from server - * - * @var string array - */ - checkForUrls: [$$getAllowedUrls$$], - /** - * Function to check if a certain url is allowed to perform the request - * With or without csrf token - * - * @param: string, url - * - * @return: boolean, true if csrftoken is not needed - * false if csrftoken is needed - */ - _isValidGetRequest: function(url) { - for (var i = 0; i < CSRFP.checkForUrls.length; i++) { - var match = CSRFP.checkForUrls[i].exec(url); - if (match !== null && match.length > 0) { - return false; - } - } - return true; - }, - /** - * function to get Auth key from cookie Andreturn it to requesting function - * - * @param: void - * - * @return: string, csrftoken retrieved from cookie - */ - _getAuthKey: function() { - var re = new RegExp(CSRFP.CSRFP_TOKEN +"=([^;]+)(;|$)"); - var RegExpArray = re.exec(document.cookie); - - if (RegExpArray === null) { - return false; - } - return RegExpArray[1]; - }, - /** - * Function to get domain of any url - * - * @param: string, url - * - * @return: string, domain of url - */ - _getDomain: function(url) { - if (url.indexOf("http://") !== 0 - && url.indexOf("https://") !== 0) - return document.domain; - return /http(s)?:\/\/([^\/]+)/.exec(url)[2]; - }, - /** - * Function to create and return a hidden input element - * For stroing the CSRFP_TOKEN - * - * @param void - * - * @return input element - */ - _getInputElt: function() { - var hiddenObj = document.createElement("input"); - hiddenObj.name = CSRFP.CSRFP_TOKEN; - hiddenObj.type = 'hidden'; - hiddenObj.value = CSRFP._getAuthKey(); - return hiddenObj; - }, - /** - * Returns absolute path for relative path - * - * @param base, base url - * @param relative, relative url - * - * @return absolute path (string) - */ - _getAbsolutePath: function(base, relative) { - var stack = base.split("/"); - var parts = relative.split("/"); - // remove current file name (or empty string) - // (omit if "base" is the current folder without trailing slash) - stack.pop(); - - for (var i = 0; i < parts.length; i++) { - if (parts[i] == ".") - continue; - if (parts[i] == "..") - stack.pop(); - else - stack.push(parts[i]); - } - return stack.join("/"); - }, - /** - * Remove jcsrfp-token run fun and then put them back - * - * @param function - * @param reference form obj - * - * @retrun function - */ - _csrfpWrap: function(fun, obj) { - return function(event) { - // Remove CSRf token if exists - if (typeof obj[CSRFP.CSRFP_TOKEN] !== 'undefined') { - var target = obj[CSRFP.CSRFP_TOKEN]; - target.parentNode.removeChild(target); - } - - // Trigger the functions - var result = fun.apply(this, [event]); - - // Now append the csrfp_token back - obj.appendChild(CSRFP._getInputElt()); - - return result; - }; - }, - /** - * Initialises the CSRFProtector js script - * - * @param void - * - * @return void - */ - _init: function() { - //convert these rules received from php lib to regex objects - for (var i = 0; i < CSRFP.checkForUrls.length; i++) { - CSRFP.checkForUrls[i] = CSRFP.checkForUrls[i].replace(/\*/g, '(.*)') - .replace(/\//g, "\\/"); - CSRFP.checkForUrls[i] = new RegExp(CSRFP.checkForUrls[i]); - } - - } - -}; - -//========================================================== -// Adding tokens, wrappers on window onload -//========================================================== - -function csrfprotector_init() { - - // Call the init funcion - CSRFP._init(); - - //================================================================== - // Adding csrftoken to request resulting from