changed CSRF token handling from GET to POST

This commit is contained in:
Roland Gruber 2018-03-14 20:06:09 +01:00
parent ca358b3975
commit 993751c7ff
8 changed files with 62 additions and 51 deletions

View File

@ -642,19 +642,20 @@ class htmlInputField extends htmlElement {
';
}
if ($this->checkPasswordStrength) {
$tokenSuffix = '?' . getSecurityTokenName() . '=' . getSecurityTokenValue();
$query = '?noselfservice=1';
if (isSelfService()) {
$tokenSuffix .= '&selfservice=1';
$query = '?selfservice=1';
}
$ajaxPath = "../templates/misc/ajax.php" . $tokenSuffix;
$ajaxPath = "../templates/misc/ajax.php";
if (is_file("../../templates/misc/ajax.php")) {
$ajaxPath = "../../templates/misc/ajax.php" . $tokenSuffix;
$ajaxPath = "../../templates/misc/ajax.php";
}
elseif (is_file("../../../templates/misc/ajax.php")) {
$ajaxPath = "../../../templates/misc/ajax.php" . $tokenSuffix;
$ajaxPath = "../../../templates/misc/ajax.php";
}
$ajaxPath .= $query;
echo '<script type="text/javascript">
checkPasswordStrength("' . $this->fieldName . '", "' . $ajaxPath . '");
checkPasswordStrength("' . $this->fieldName . '", "' . $ajaxPath . '", "' . getSecurityTokenName() . '", "' . getSecurityTokenValue() . '");
</script>
';
}

View File

@ -2,10 +2,9 @@
use LAM\TYPES\ConfiguredType;
use \LAM\TYPES\TypeManager;
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2017 Roland Gruber
Copyright (C) 2003 - 2018 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -1278,8 +1277,8 @@ class accountContainer {
$passwordButton = new htmlButton('accountContainerPassword', _('Set password'));
$passwordButton->setIconClass('passwordButton');
$passwordButton->setOnClick('passwordShowChangeDialog(\'' . _('Set password') . '\', \'' . _('Ok') . '\', \''
. _('Cancel') . '\', \'' . _('Set random password') . '\', \'../misc/ajax.php?function=passwordChange&'
. getSecurityTokenName() . '=' . getSecurityTokenValue() . '\');');
. _('Cancel') . '\', \'' . _('Set random password') . '\', \'../misc/ajax.php?function=passwordChange\',\''
. getSecurityTokenName() . '\',\'' . getSecurityTokenValue() . '\');');
$leftButtonGroup->addElement($passwordButton);
}
$table->addElement($leftButtonGroup);

View File

@ -1,11 +1,10 @@
<?php
use \LAM\TYPES\TypeManager;
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2006 Tilo Lutz
2005 - 2017 Roland Gruber
2005 - 2018 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -2954,9 +2953,10 @@ class inetOrgPerson extends baseModule implements passwordService {
"action": "delete",
"id": id
};
jQuery.post(\'../misc/ajax.php?selfservice=1&module=inetOrgPerson&scope=user'
. '&' . getSecurityTokenName() . '=' . getSecurityTokenValue()
. '\', {jsonInput: actionJSON}, function(data) {inetOrgPersonDeleteCertificateHandleReply(data);}, \'json\');
var data = {jsonInput: actionJSON};
data["' . getSecurityTokenName() . '"] = "' . getSecurityTokenValue() . '";
jQuery.post(\'../misc/ajax.php?selfservice=1&module=inetOrgPerson&scope=user\',
data, function(data) {inetOrgPersonDeleteCertificateHandleReply(data);}, \'json\');
}
function inetOrgPersonDeleteCertificateHandleReply(data) {
@ -2970,6 +2970,8 @@ class inetOrgPerson extends baseModule implements passwordService {
function inetOrgPersonUploadCert(elementID) {
var uploadStatus = document.getElementById(\'inetOrgPerson_upload_status_cert\');
var params = { action: \'ajaxCertUpload\' };
params["' . getSecurityTokenName() . '"] = "' . getSecurityTokenValue() . '";
var uploader = new qq.FineUploader({
element: document.getElementById(elementID),
listElement: uploadStatus,
@ -2977,9 +2979,7 @@ class inetOrgPerson extends baseModule implements passwordService {
endpoint: \'../misc/ajax.php?selfservice=1&module=inetOrgPerson&scope=user'
. '&' . getSecurityTokenName() . '=' . getSecurityTokenValue() . '\',
forceMultipart: true,
params: {
action: \'ajaxCertUpload\'
}
params: params
},
multiple: false,
callbacks: {

View File

@ -3,10 +3,9 @@ use \LAM\PDF\PDFTable;
use \LAM\PDF\PDFTableCell;
use \LAM\PDF\PDFTableRow;
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2005 - 2017 Roland Gruber
Copyright (C) 2005 - 2018 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -392,9 +391,10 @@ class ldapPublicKey extends baseModule {
for (c = 0; c < count; c++) {
actionJSON["sshPublicKey_" + c] = jQuery(\'#sshPublicKey_\' + c).val();
}
jQuery.post(\'../misc/ajax.php?selfservice=1&module=ldapPublicKey&scope=user'
. '&' . getSecurityTokenName() . '=' . getSecurityTokenValue()
. '\', {jsonInput: actionJSON}, function(data) {ldapPublicKeyDeleteKeyHandleReply(data);}, \'json\');
var data = {jsonInput: actionJSON};
data["' . getSecurityTokenName() . '"] = "' . getSecurityTokenValue() . '";
jQuery.post(\'../misc/ajax.php?selfservice=1&module=ldapPublicKey&scope=user\',
data, function(data) {ldapPublicKeyDeleteKeyHandleReply(data);}, \'json\');
}
function ldapPublicKeyDeleteKeyHandleReply(data) {
@ -413,9 +413,11 @@ class ldapPublicKey extends baseModule {
for (c = 0; c < count; c++) {
actionJSON["sshPublicKey_" + c] = jQuery(\'#sshPublicKey_\' + c).val();
}
var data = {jsonInput: actionJSON};
data["' . getSecurityTokenName() . '"] = "' . getSecurityTokenValue() . '";
jQuery.post(\'../misc/ajax.php?selfservice=1&module=ldapPublicKey&scope=user'
. '&' . getSecurityTokenName() . '=' . getSecurityTokenValue()
. '\', {jsonInput: actionJSON}, function(data) {ldapPublicKeyAddKeyHandleReply(data);}, \'json\');
. '\', data, function(data) {ldapPublicKeyAddKeyHandleReply(data);}, \'json\');
}
function ldapPublicKeyAddKeyHandleReply(data) {
@ -435,12 +437,12 @@ class ldapPublicKey extends baseModule {
for (c = 0; c < count; c++) {
parameters["sshPublicKey_" + c] = jQuery(\'#sshPublicKey_\' + c).val();
}
parameters["' . getSecurityTokenName() . '"] = "' . getSecurityTokenValue() . '";
var uploader = new qq.FineUploader({
element: document.getElementById(elementID),
listElement: uploadStatus,
request: {
endpoint: \'../misc/ajax.php?selfservice=1&module=ldapPublicKey&scope=user'
. '&' . getSecurityTokenName() . '=' . getSecurityTokenValue() . '\',
endpoint: \'../misc/ajax.php?selfservice=1&module=ldapPublicKey&scope=user\',
forceMultipart: true,
paramsInBody: true,
params: parameters

View File

@ -548,17 +548,13 @@ function addSecurityTokenToSession($overwrite = true) {
/**
* Checks if the security token from SESSION matches POST data.
*
* @param $post use POST, set to false for GET (default: true)
*/
function validateSecurityToken($post = true) {
$vars = $post ? $_POST : $_GET;
if (empty($vars)) {
function validateSecurityToken() {
if (empty($_POST)) {
return;
}
if (empty($vars[getSecurityTokenName()]) || ($vars[getSecurityTokenName()] != $_SESSION[getSecurityTokenName()])) {
$method = $post ? 'POST' : 'GET';
logNewMessage(LOG_ERR, 'Security token does not match ' . $method . ' data.');
if (empty($_POST[getSecurityTokenName()]) || ($_POST[getSecurityTokenName()] != $_SESSION[getSecurityTokenName()])) {
logNewMessage(LOG_ERR, 'Security token does not match POST data.');
die();
}
}

View File

@ -1,9 +1,7 @@
/**
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2017 Roland Gruber
Copyright (C) 2003 - 2018 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -236,11 +234,13 @@ function showSimpleDialog(title, okText, cancelText, formID, dialogDivID) {
* @param cancelText text for Cancel button
* @param randomText text for random password
* @param ajaxURL URL used for AJAX request
* @param tokenName name of CSRF token
* @param tokenValue value of CSRF token
*/
function passwordShowChangeDialog(title, okText, cancelText, randomText, ajaxURL) {
function passwordShowChangeDialog(title, okText, cancelText, randomText, ajaxURL, tokenName, tokenValue) {
var buttonList = {};
buttonList[okText] = function() { passwordHandleInput("false", ajaxURL); };
buttonList[randomText] = function() { passwordHandleInput("true", ajaxURL); };
buttonList[okText] = function() { passwordHandleInput("false", ajaxURL, tokenName, tokenValue); };
buttonList[randomText] = function() { passwordHandleInput("true", ajaxURL, tokenName, tokenValue); };
buttonList[cancelText] = function() {
jQuery('#passwordDialogMessageArea').html("");
jQuery(this).dialog("close");
@ -262,8 +262,10 @@ function passwordShowChangeDialog(title, okText, cancelText, randomText, ajaxURL
*
* @param random "true" if random password should be generated
* @param ajaxURL URL used for AJAX request
* @param tokenName name of CSRF token
* @param tokenValue value of CSRF token
*/
function passwordHandleInput(random, ajaxURL) {
function passwordHandleInput(random, ajaxURL, tokenName, tokenValue) {
// get input values
var modules = new Array();
jQuery('#passwordDialog').find(':checked').each(function() {
@ -286,8 +288,10 @@ function passwordHandleInput(random, ajaxURL) {
"sendMail": sendMail,
"sendMailAlternateAddress": sendMailAlternateAddress
};
var data = {jsonInput: pwdJSON};
data[tokenName] = tokenValue;
// make AJAX call
jQuery.post(ajaxURL, {jsonInput: pwdJSON}, function(data) {passwordHandleReply(data);}, 'json');
jQuery.post(ajaxURL, data, function(data) {passwordHandleReply(data);}, 'json');
}
/**
@ -551,8 +555,10 @@ function checkFieldsHaveSameValues(fieldID, fieldIDReference) {
* Field is marked red if fail and green if ok.
*
* @param fieldID ID of field to check
* @param tokenName name of CSRF token
* @param tokenValue value of CSRF token
*/
function checkPasswordStrength(fieldID, ajaxURL) {
function checkPasswordStrength(fieldID, ajaxURL, tokenName, tokenValue) {
var field = jQuery('#' + fieldID);
var check =
function() {
@ -560,8 +566,10 @@ function checkPasswordStrength(fieldID, ajaxURL) {
var pwdJSON = {
"password": value
};
var data = {jsonInput: pwdJSON};
data[tokenName] = tokenValue;
// make AJAX call
jQuery.post(ajaxURL + "&function=passwordStrengthCheck", {jsonInput: pwdJSON}, function(data) {checkPasswordStrengthHandleReply(data, fieldID);}, 'json');
jQuery.post(ajaxURL + "&function=passwordStrengthCheck", data, function(data) {checkPasswordStrengthHandleReply(data, fieldID);}, 'json');
};
jQuery(field).keyup(check);
}
@ -654,12 +662,18 @@ window.lam.upload = window.lam.upload || {};
* Continues a CSV file upload.
*
* @param url URL where to get status JSON
* @param tokenName name of CSRF token
* @param tokenValue value of CSRF token
*/
window.lam.upload.continueUpload = function(url) {
window.lam.upload.continueUpload = function(url, tokenName, tokenValue) {
var data = {
jsonInput: ''
};
data[tokenName] = tokenValue;
jQuery.ajax({
url: url,
method: 'POST',
data: 'jsonInput='
data: data
})
.done(function(jsonData){
if (!jsonData.accountsFinished) {
@ -673,7 +687,7 @@ window.lam.upload.continueUpload = function(url) {
}
// next call if not finished
if (!jsonData.allDone) {
window.lam.upload.continueUpload(url);
window.lam.upload.continueUpload(url, tokenName, tokenValue);
}
else {
window.lam.upload.uploadDone(jsonData);

View File

@ -61,7 +61,7 @@ class Ajax {
public function handleRequest() {
$this->setHeader();
// check token
validateSecurityToken(false);
validateSecurityToken();
if (isset($_GET['module']) && isset($_GET['scope']) && in_array($_GET['module'], getAvailableModules($_GET['scope']))) {
enforceUserIsLoggedIn();

View File

@ -1,10 +1,9 @@
<?php
namespace LAM\UPLOAD;
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2004 - 2017 Roland Gruber
Copyright (C) 2004 - 2018 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -82,7 +81,7 @@ $tokenPrefix = '?' . getSecurityTokenName() . '=' . getSecurityTokenValue();
?>
<script type="text/javascript">
jQuery(document).ready(function(){
window.lam.upload.continueUpload('../misc/ajax.php' + '<?php echo $tokenPrefix; ?>' + '&function=upload&typeId=' + '<?php echo $type->getId() ?>');
window.lam.upload.continueUpload('../misc/ajax.php?function=upload&typeId=' + '<?php echo $type->getId() ?>', '<?php echo getSecurityTokenName(); ?>', '<?php echo getSecurityTokenValue(); ?>');
});
</script>