Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add CSRF checks to additional endpoints
  • Loading branch information
collectiveaccess committed Sep 26, 2021
1 parent 8ef8885 commit 23bb11f
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 14 deletions.
8 changes: 6 additions & 2 deletions app/controllers/manage/PawtucketController.php
Expand Up @@ -7,7 +7,7 @@
* ----------------------------------------------------------------------
*
* Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
* Copyright 2016 Whirl-i-Gig
* Copyright 2016-2021 Whirl-i-Gig
*
* For more information visit http://www.CollectiveAccess.org
*
Expand Down Expand Up @@ -124,6 +124,10 @@ public function editGlobalValues() {
*
*/
public function saveGlobalValues() {
if (!caValidateCSRFToken($this->request, null, ['notifications' => $this->notification])) {
$this->editGlobalValues();
return;
}
if(!$this->request->getUser()->canDoAction('can_edit_theme_global_values')) { throw new ApplicationException("No access"); }
if (caGetGlobalValuesCount() == 0) { throw new ApplicationException("No global values defined"); }

Expand Down Expand Up @@ -157,4 +161,4 @@ public function Info() {
return $this->render('Pawtucket/widget_pawtucket_info_html.php', true);
}
# -------------------------------------------------------
}
}
4 changes: 4 additions & 0 deletions app/controllers/manage/sets/SetEditorController.php
Expand Up @@ -254,6 +254,10 @@ public function getSetMedia() {
*
*/
public function DuplicateItems() {
if (!caValidateCSRFToken($this->request, null, ['notifications' => $this->notification])) {
$this->Edit();
return;
}
$t_set = new ca_sets($this->getRequest()->getParameter('set_id', pInteger));
if(!$t_set->getPrimaryKey()) { return; }

Expand Down
8 changes: 4 additions & 4 deletions app/helpers/displayHelpers.php
Expand Up @@ -1145,7 +1145,7 @@ function caEditorInspector($po_view, $pa_options=null) {
function caToggleItemWatch() {
var url = '".caNavUrl($po_view->request, $po_view->request->getModulePath(), $po_view->request->getController(), 'toggleWatch', array($t_item->primaryKey() => $vn_item_id))."';
jQuery.getJSON(url, {}, function(data, status) {
jQuery.getJSON(url, {'csrfToken': ".json_encode(caGenerateCSRFToken($po_view->request))."}, function(data, status) {
if (data['status'] == 'ok') {
jQuery('#caWatchItemButton').html((data['state'] == 'watched') ? '".addslashes(caNavIcon(__CA_NAV_ICON_UNWATCH__, '20px'))."' : '".addslashes(caNavIcon(__CA_NAV_ICON_WATCH__, '20px'))."');
} else {
Expand Down Expand Up @@ -1204,7 +1204,7 @@ function caToggleItemWatch() {
if($po_view->request->user->canDoAction('can_duplicate_'.$vs_table_name) && $t_item->getPrimaryKey()) {
$vs_buf .= '<div id="caDuplicateItemButton">';

$vs_buf .= caFormTag($po_view->request, 'Edit', 'DuplicateItemForm', $po_view->request->getModulePath().'/'.$po_view->request->getController(), 'post', 'multipart/form-data', '_top', array('noCSRFToken' => true, 'disableUnsavedChangesWarning' => true, 'noTimestamp' => true));
$vs_buf .= caFormTag($po_view->request, 'Edit', 'DuplicateItemForm', $po_view->request->getModulePath().'/'.$po_view->request->getController(), 'post', 'multipart/form-data', '_top', array('noCSRFToken' => false, 'disableUnsavedChangesWarning' => true, 'noTimestamp' => true));
$vs_buf .= "<div>".caFormSubmitLink($po_view->request, caNavIcon(__CA_NAV_ICON_DUPLICATE__, '20px'), '', 'DuplicateItemForm')."</div>";

$vs_buf .= caHTMLHiddenInput($t_item->primaryKey(), array('value' => $t_item->getPrimaryKey()));
Expand Down Expand Up @@ -1511,7 +1511,7 @@ function caAddObjectToLotForm() {

if(!(bool)$po_view->request->config->get('ca_sets_disable_duplication_of_items') && $po_view->request->user->canDoAction('can_duplicate_items_in_sets') && $po_view->request->user->canDoAction('can_duplicate_' . $vs_set_table_name)) {
$vs_buf .= '<div style="border-top: 1px solid #aaaaaa; margin-top: 5px; font-size: 10px; text-align: right;" ></div>';
$vs_buf .= caFormTag($po_view->request, 'DuplicateItems', 'caDupeSetItemsForm', 'manage/sets/SetEditor', 'post', 'multipart/form-data', '_top', array('noCSRFToken' => true, 'disableUnsavedChangesWarning' => true));
$vs_buf .= caFormTag($po_view->request, 'DuplicateItems', 'caDupeSetItemsForm', 'manage/sets/SetEditor', 'post', 'multipart/form-data', '_top', array('noCSRFToken' => false, 'disableUnsavedChangesWarning' => true));
$vs_buf .= _t("Duplicate items in this set and add to") . " ";
$vs_buf .= caHTMLSelect('setForDupes', array(
_t('current set') => 'current',
Expand Down Expand Up @@ -1605,7 +1605,7 @@ function caAddObjectToLotForm() {

if ($vs_type_list) {
$vs_buf .= '<div style="border-top: 1px solid #aaaaaa; margin-top: 5px; font-size: 10px;">';
$vs_buf .= caFormTag($po_view->request, 'Edit', 'NewChildForm', 'administrate/setup/list_item_editor/ListItemEditor', 'post', 'multipart/form-data', '_top', array('noCSRFToken' => true, 'disableUnsavedChangesWarning' => true));
$vs_buf .= caFormTag($po_view->request, 'Edit', 'NewChildForm', 'administrate/setup/list_item_editor/ListItemEditor', 'post', 'multipart/form-data', '_top', array('noCSRFToken' => false, 'disableUnsavedChangesWarning' => true));
$vs_buf .= _t('Add a %1 to this list', $vs_type_list).caHTMLHiddenInput($t_list_item->primaryKey(), array('value' => '0')).caHTMLHiddenInput('parent_id', array('value' => $t_list_item->getPrimaryKey()));
$vs_buf .= caFormSubmitLink($po_view->request, caNavIcon(__CA_NAV_ICON_ADD__, '18px'), '', 'NewChildForm');
$vs_buf .= "</form></div>\n";
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/navigationHelpers.php
Expand Up @@ -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)) {
Expand Down
4 changes: 2 additions & 2 deletions app/helpers/utilityHelpers.php
Expand Up @@ -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]
Expand All @@ -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])) {
Expand Down
22 changes: 21 additions & 1 deletion app/lib/BaseEditorController.php
Expand Up @@ -7,7 +7,7 @@
* ----------------------------------------------------------------------
*
* Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
* Copyright 2009-2018 Whirl-i-Gig
* Copyright 2009-2021 Whirl-i-Gig
*
* For more information visit http://www.CollectiveAccess.org
*
Expand Down Expand Up @@ -91,6 +91,10 @@ public function Edit($pa_values=null, $pa_options=null) {
// Are we duplicating?
//
if (($vs_mode == 'dupe') && $this->request->user->canDoAction('can_duplicate_'.$t_subject->tableName())) {
if (!caValidateCSRFToken($this->request, null, ['notifications' => $this->notification])) {
throw new ApplicationException(_t('CSRF check failed'));
return;
}
if (!($vs_type_name = $t_subject->getTypeName())) {
$vs_type_name = $t_subject->getProperty('NAME_SINGULAR');
}
Expand Down Expand Up @@ -1027,6 +1031,10 @@ public function Access($pa_options=null) {
* @param array $pa_options Array of options passed through to _initView
*/
public function SetAccess($pa_options=null) {
if (!caValidateCSRFToken($this->request, null, ['notifications' => $this->notification])) {
throw new ApplicationException(_t('CSRF check failed'));
return;
}
list($vn_subject_id, $t_subject) = $this->_initView($pa_options);


Expand Down Expand Up @@ -1454,6 +1462,10 @@ public function getResultContext() {
* Export data is rendered into the current view inherited from ActionController
*/
public function exportItem() {
if (!caValidateCSRFToken($this->request, null, ['notifications' => $this->notification])) {
throw new ApplicationException(_t('CSRF check failed'));
return;
}
list($vn_subject_id, $t_subject) = $this->_initView();

if (!$this->_checkAccess($t_subject)) { return false; }
Expand All @@ -1474,6 +1486,10 @@ public function exportItem() {
* Add item to user's watch list. Intended to be called via ajax, and JSON response is returned in the current view inherited from ActionController
*/
public function toggleWatch() {
if (!caValidateCSRFToken($this->request, null, ['notifications' => $this->notification])) {
throw new ApplicationException(_t('CSRF check failed'));
return;
}
list($vn_subject_id, $t_subject) = $this->_initView();
require_once(__CA_MODELS_DIR__.'/ca_watch_list.php');

Expand Down Expand Up @@ -2187,6 +2203,10 @@ public function GetAnnotations() {
*
*/
public function SaveAnnotations() {
if (!caValidateCSRFToken($this->request, null, ['notifications' => $this->notification])) {
throw new ApplicationException(_t('CSRF check failed'));
return;
}
global $g_ui_locale_id;
$pn_representation_id = $this->request->getParameter('representation_id', pInteger);
$t_rep = new ca_object_representations($pn_representation_id);
Expand Down
4 changes: 2 additions & 2 deletions themes/default/views/bundles/change_type_html.php
Expand Up @@ -7,7 +7,7 @@
* ----------------------------------------------------------------------
*
* Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
* Copyright 2012-2019 Whirl-i-Gig
* Copyright 2012-2021 Whirl-i-Gig
*
* For more information visit http://www.CollectiveAccess.org
*
Expand Down Expand Up @@ -55,7 +55,7 @@
<div id="caTypeChangePanel" class="caTypeChangePanel">
<div class='dialogHeader'><?php print _t('Change %1 type', $t_item->getProperty('NAME_SINGULAR')); ?></div>
<div id="caTypeChangePanelContentArea">
<?php print caFormTag($this->request, 'ChangeType', 'caChangeTypeForm', null, 'post', 'multipart/form-data', '_top', ['noCSRFToken' => true, 'disableUnsavedChangesWarning' => true]); ?>
<?php print caFormTag($this->request, 'ChangeType', 'caChangeTypeForm', null, 'post', 'multipart/form-data', '_top', ['noCSRFToken' => false, 'disableUnsavedChangesWarning' => true]); ?>
<p><?php print _t('<strong>Warning:</strong> changing the %1 type will cause information in all fields not applicable to the new type to be discarded. This action cannot be undone.', $t_item->getProperty('NAME_SINGULAR')); ?></p>
<p><?php print ($vs_typename = $t_item->getTypeName()) ?
_t('Change type from <em>%1</em> to %2', $vs_typename, $t_item->getTypeListAsHTMLFormElement('type_id', array('id' => 'caChangeTypeFormTypeID'), array('omitItemsWithID' => array($t_item->getTypeID()), 'childrenOfCurrentTypeOnly' => false, 'directChildrenOnly' => false, 'returnHierarchyLevels' => true, 'access' => __CA_BUNDLE_ACCESS_EDIT__)))
Expand Down
Expand Up @@ -7,7 +7,7 @@
* ----------------------------------------------------------------------
*
* Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
* Copyright 2016 Whirl-i-Gig
* Copyright 2016-2021 Whirl-i-Gig
*
* For more information visit http://www.CollectiveAccess.org
*
Expand Down Expand Up @@ -49,7 +49,7 @@
</div>
<div style="clear:both; height:1px;"><!-- empty --></div>
<?php
print caFormTag($this->request, 'saveGlobalValues', 'globalValuesForm', null, 'post', 'multipart/form-data', '_top', ['noCSRFToken' => true, 'disableUnsavedChangesWarning' => true]);
print caFormTag($this->request, 'saveGlobalValues', 'globalValuesForm', null, 'post', 'multipart/form-data', '_top', ['noCSRFToken' => false, 'disableUnsavedChangesWarning' => true]);

if (sizeof($va_form_elements) > 0) {
foreach($va_form_elements as $vs_name => $va_info) {
Expand Down

0 comments on commit 23bb11f

Please sign in to comment.