diff --git a/app/controllers/DetailController.php b/app/controllers/DetailController.php index 51d9da3c4b..83b905754c 100644 --- a/app/controllers/DetailController.php +++ b/app/controllers/DetailController.php @@ -823,6 +823,10 @@ public function CommentForm(){ * */ public function SaveCommentTagging() { + if (!caValidateCSRFToken($this->request)) { + throw new ApplicationException(_t("Invalid CSRF token")); + } + # --- inline is passed to indicate form appears embedded in detail page, not in overlay $vn_inline_form = $this->request->getParameter("inline", pInteger); if(!$t_item = Datamodel::getInstance($this->request->getParameter("tablename", pString), true)) { diff --git a/app/controllers/LightboxController.php b/app/controllers/LightboxController.php index 36233af1fd..ae926f8103 100644 --- a/app/controllers/LightboxController.php +++ b/app/controllers/LightboxController.php @@ -943,6 +943,9 @@ function ajaxListComments() { */ function ajaxAddComment() { if($this->opb_is_login_redirect) { return; } + if (!caValidateCSRFToken($this->request)) { + throw new ApplicationException(_t("Invalid CSRF token")); + } // when close is set to true, will make the form view disappear after saving form @@ -1000,7 +1003,9 @@ function ajaxAddComment() { */ function ajaxDeleteComment() { if($this->opb_is_login_redirect) { return; } - + if (!caValidateCSRFToken($this->request)) { + throw new ApplicationException(_t("Invalid CSRF token")); + } $va_errors = array(); $vs_message = null; $vn_count = null; @@ -1018,7 +1023,6 @@ function ajaxDeleteComment() { if (($this->request->getUserID() != $t_comment->get("user_id")) && !$t_set->haveAccessToSet($this->request->getUserID(), __CA_SET_EDIT_ACCESS__)) { $va_errors[] = _t('You do not have access to this comment'); } else { - $t_comment->setMode(ACCESS_WRITE); $t_comment->delete(true); if ($t_comment->numErrors()) { $va_errors = $t_comment->getErrors(); @@ -1045,7 +1049,9 @@ function ajaxDeleteComment() { */ public function deleteLightbox() { if($this->opb_is_login_redirect) { return; } - + if (!caValidateCSRFToken($this->request)) { + throw new ApplicationException(_t("Invalid CSRF token")); + } $va_errors = array(); $vs_message = $vn_set_id = $vs_set_name = null; @@ -1100,6 +1106,9 @@ public function ajaxReorderItems() { */ public function ajaxDeleteItem() { if($this->opb_is_login_redirect) { return; } + if (!caValidateCSRFToken($this->request)) { + throw new ApplicationException(_t("Invalid CSRF token")); + } if($t_set = $this->_getSet(__CA_SET_EDIT_ACCESS__)){ @@ -1125,6 +1134,9 @@ public function ajaxDeleteItem() { */ public function ajaxAddItem($pa_options = null) { if($this->opb_is_login_redirect) { return; } + if (!caValidateCSRFToken($this->request)) { + throw new ApplicationException(_t("Invalid CSRF token")); + } global $g_ui_locale_id; // current locale_id for user $va_errors = array(); diff --git a/app/helpers/navigationHelpers.php b/app/helpers/navigationHelpers.php index 2846d95557..d68c3bddbe 100644 --- a/app/helpers/navigationHelpers.php +++ b/app/helpers/navigationHelpers.php @@ -420,7 +420,7 @@ function caFormTag($po_request, $ps_action, $ps_id, $ps_module_and_controller_pa $vs_buf .= caHTMLHiddenInput('form_timestamp', array('value' => time())); } if (!caGetOption('noCSRFToken', $pa_options, false)) { - $vs_buf .= caHTMLHiddenInput('crsfToken', array('value' => caGenerateCSRFToken($po_request))); + $vs_buf .= caHTMLHiddenInput('csrfToken', array('value' => caGenerateCSRFToken($po_request))); } if (!caGetOption('disableUnsavedChangesWarning', $pa_options, false)) { diff --git a/app/helpers/utilityHelpers.php b/app/helpers/utilityHelpers.php index fcd0199caf..899adcf90c 100644 --- a/app/helpers/utilityHelpers.php +++ b/app/helpers/utilityHelpers.php @@ -3611,7 +3611,7 @@ function caGenerateCSRFToken($po_request=null){ * Validate CSRF token using current session * * @param RequestHTTP $po_request Current request - * @param string $ps_token CSRF token to validate. If omitted token in the "crsfToken" parameter is extracted from current request. + * @param string $ps_token CSRF token to validate. If omitted token in the "csrfToken" parameter is extracted from current request. * @param array $pa_options Options include: * remove = remove validated token from active token list. [Default is true] * exceptions = throw exception if token is invalid. [Default is true] @@ -3621,7 +3621,7 @@ function caGenerateCSRFToken($po_request=null){ function caValidateCSRFToken($po_request, $ps_token=null, $pa_options=null){ $session_id = $po_request ? $po_request->getSessionID() : 'none'; - if(!$ps_token) { $ps_token = $po_request->getParameter('crsfToken', pString); } + if(!$ps_token) { $ps_token = $po_request->getParameter('csrfToken', pString); } if (!is_array($va_tokens = PersistentCache::fetch("csrf_tokens_{$session_id}", "csrf_tokens"))) { $va_tokens = []; } if (isset($va_tokens[$ps_token])) { diff --git a/themes/default/views/Classroom/list_html.php b/themes/default/views/Classroom/list_html.php index 14a0b76d88..403a90cf31 100644 --- a/themes/default/views/Classroom/list_html.php +++ b/themes/default/views/Classroom/list_html.php @@ -203,7 +203,7 @@ jQuery('#confirm-delete .btn-delete').data('set_id', set_id); }).find('.btn-delete').on('click', function(e) { var set_id = jQuery(this).data('set_id'); - jQuery.getJSON('request, '*', '*', 'DeleteLightbox'); ?>', {'set_id': set_id }, function(data) { + jQuery.getJSON('request, '*', '*', 'DeleteLightbox'); ?>', {'set_id': set_id, 'csrfToken': = json_encode(caGenerateCSRFToken($this->request)); ?> }, function(data) { if(data.status == 'ok') { jQuery("#crSetContainer" + set_id).parent().remove(); if (jQuery('.crSetContainer').length == 0) { jQuery('#crSetListPlaceholder').show(); } else { jQuery('#crSetListPlaceholder').hide(); } diff --git a/themes/default/views/Classroom/set_detail_html.php b/themes/default/views/Classroom/set_detail_html.php index edc5fd33e6..2aa1943614 100644 --- a/themes/default/views/Classroom/set_detail_html.php +++ b/themes/default/views/Classroom/set_detail_html.php @@ -433,7 +433,7 @@ jQuery('#confirm-delete .btn-delete').data('set_id', set_id); }).find('.btn-delete').on('click', function(e) { var set_id = jQuery(this).data('set_id'); - jQuery.getJSON('request, '*', '*', 'DeleteLightbox'); ?>', {'set_id': set_id }, function(data) { + jQuery.getJSON('request, '*', '*', 'DeleteLightbox'); ?>', {'set_id': set_id, 'csrfToken': = json_encode(caGenerateCSRFToken($this->request)); ?> }, function(data) { if(data.status == 'ok') { jQuery("#crSetContainer" + set_id).remove(); jQuery("#crUserResponse").html(' '); @@ -499,7 +499,7 @@ var data = $(this).sortable('serialize'); jQuery.ajax({ type: 'POST', - url: 'request, "", "Lightbox", "AjaxReorderItems"); ?>/row_ids/' + data + url: 'request, "", "Lightbox", "AjaxReorderItems", ['csrfToken' => caGenerateCSRFToken($this->request)]); ?>/row_ids/' + data }); } }); @@ -507,7 +507,7 @@ jQuery("#lbSetResultLoadContainer").on('click', ".lbItemDeleteButton", function(e) { var id = jQuery(this).data("item_id"); - jQuery.getJSON('request, '', 'Lightbox', 'AjaxDeleteItem'); ?>', {'set_id': 'get("set_id"); ?>', 'item_id':id} , function(data) { + jQuery.getJSON('request, '', 'Lightbox', 'AjaxDeleteItem'); ?>', {'set_id': 'get("set_id"); ?>', 'item_id':id, 'csrfToken': = json_encode(caGenerateCSRFToken($this->request)); ?>} , function(data) { if(data.status == 'ok') { jQuery('.lbItem' + data.item_id).fadeOut(500, function() { jQuery('.lbItem' + data.item_id).remove(); }); jQuery('.lbSetCountInt').html(data.count); // update count @@ -522,7 +522,7 @@ ); jQuery("#addComment").on('submit', function(e) { - jQuery.getJSON('request, '', 'Lightbox', 'AjaxAddComment'); ?>', {'id': 'get("set_id"); ?>', 'type': 'ca_sets', 'comment': jQuery("#addCommentTextArea").val() } , function(data) { + jQuery.getJSON('request, '', 'Lightbox', 'AjaxAddComment'); ?>', {'id': 'get("set_id"); ?>', 'type': 'ca_sets', 'comment': jQuery("#addCommentTextArea").val(), 'csrfToken': = json_encode(caGenerateCSRFToken($this->request)); ?> } , function(data) { if(data.status == 'ok') { jQuery("#lbSetCommentErrors").hide() jQuery("#addCommentTextArea").val(''); @@ -541,7 +541,7 @@ jQuery("div.lbComments").on('click', '.lbComment', function(e) { var comment_id = jQuery(this).data("comment_id"); if(comment_id) { - jQuery.getJSON('request, '', 'Lightbox', 'AjaxDeleteComment'); ?>', {'comment_id': comment_id }, function(data) { + jQuery.getJSON('request, '', 'Lightbox', 'AjaxDeleteComment'); ?>', {'comment_id': comment_id, 'csrfToken': = json_encode(caGenerateCSRFToken($this->request)); ?> }, function(data) { if(data.status == 'ok') { jQuery("#lbSetCommentErrors").hide() jQuery("#lbComments" + data.comment_id).remove(); @@ -565,4 +565,4 @@ \ No newline at end of file +?> diff --git a/themes/default/views/Details/form_comments_html.php b/themes/default/views/Details/form_comments_html.php index c5f783bd63..fb4c6dc017 100644 --- a/themes/default/views/Details/form_comments_html.php +++ b/themes/default/views/Details/form_comments_html.php @@ -10,6 +10,7 @@ ?>