Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion js/csrfprotector.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ var CSRFP = {
*
* @var string array
*/
checkForUrls: [],
checkForUrls: Array.prototype.slice.call(document.getElementsByName("CSRFP_checkForUrls"))
.map(function (element) {
return element.value;
}),
/**
* Function to check if a certain url is allowed to perform the request
* With or without csrf token
Expand Down Expand Up @@ -314,3 +317,7 @@ function csrfprotector_init() {
}

}

window.addEventListener("DOMContentLoaded", function() {
csrfprotector_init();
}, false);
26 changes: 11 additions & 15 deletions libs/csrf/csrfprotector.php
Original file line number Diff line number Diff line change
Expand Up @@ -396,33 +396,29 @@ public static function ob_handler($buffer, $flags)
$buffer = preg_replace("/<body[^>]*>/", "$0 <noscript>" .self::$config['disabledJavascriptMessage'] .
"</noscript>", $buffer);

$arrayStr = '';
$urls = array();
if (!self::useCachedVersion()) {
try {
self::createNewJsCache();
} catch (exception $ex) {
if (self::$config['verifyGetFor']) {
foreach (self::$config['verifyGetFor'] as $key => $value) {
if ($key != 0) $arrayStr .= ',';
$arrayStr .= "'". $value ."'";
}
$urls = self::$config['verifyGetFor'];
}
}
}

$script = '<script type="text/javascript" src="' .self::$config['jsUrl']
.'"></script>' .PHP_EOL;

$script .= '<script type="text/javascript">' .PHP_EOL;
if ($arrayStr !== '') {
$script .= 'CSRFP.checkForUrls = [' .$arrayStr .'];' .PHP_EOL;
//implant hidden fields with check url information for reading in javascript
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally when the config file is changed the main js file is automatically changed, that's what self::createNewJsCache(); LINE#202 does. Now if due to file permission error it fails, we had to insert the urls inline so that the system doesn't fail.
So insert this hidden field only when say count($urls) > 0. Also JS should try to retrieve urls from the hidden field only when the hidden field is available.
Initiating the init() on onload event is good, and we need to be compliant with CSP rules.

if (count($urls) > 0) {
$hiddenInput = function ($str) {
return sprintf('<input type="hidden" name="CSRFP_checkForUrls" value="%s"></input>', $str);
};
$hiddenInputUrls = array_map($hiddenInput, $urls);
$hiddenInputUrlStr = implode(PHP_EOL, $hiddenInputUrls);
$buffer = str_ireplace('</body>', $hiddenInputUrlStr . '</body>', $buffer);
}
$script .= 'window.onload = function() {' .PHP_EOL;
$script .= ' csrfprotector_init();' .PHP_EOL;
$script .= '};' .PHP_EOL;
$script .= '</script>' .PHP_EOL;

//implant the CSRFGuard js file to outgoing script
$script = '<script type="text/javascript" src="' . self::$config['jsUrl'] . '"></script>' . PHP_EOL;
$buffer = str_ireplace('</body>', $script . '</body>', $buffer, $count);
if (!$count)
$buffer .= $script;
Expand Down