Skip to content

Commit 985390f

Browse files
author
Marius Cramer
committed
Merge branch 'stable-3.0.5'
Conflicts: interface/lib/classes/tform.inc.php interface/web/monitor/show_sys_state.php interface/web/themes/default/templates/tabbed_form.tpl.htm
2 parents 6b1fde7 + 582cbf7 commit 985390f

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

interface/lib/classes/tform_base.inc.php

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,30 @@ function getHTML($record, $tab, $action = 'NEW') {
414414
if(!is_array($this->formDef)) $app->error("No form definition found.");
415415
if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
416416

417+
/* CSRF PROTECTION */
418+
// generate csrf protection id and key
419+
$_csrf_id = uniqid($this->formDef['name'] . '_');
420+
$_csrf_value = sha1(uniqid(microtime(true), true));
421+
if(!isset($_SESSION['_csrf'])) $_SESSION['_csrf'] = array();
422+
if(!isset($_SESSION['_csrf_timeout'])) $_SESSION['_csrf_timeout'] = array();
423+
$_SESSION['_csrf'][$_csrf_id] = $_csrf_value;
424+
$_SESSION['_csrf_timeout'][$_csrf_id] = time() + 3600; // timeout hash in 1 hour
425+
$this->formDef['tabs'][$tab]['fields']['_csrf_id'] = array(
426+
'datatype' => 'VARCHAR',
427+
'formtype' => 'TEXT',
428+
'default' => $_csrf_id,
429+
'value' => $_csrf_id
430+
);
431+
$this->formDef['tabs'][$tab]['fields']['_csrf_key'] = array(
432+
'datatype' => 'VARCHAR',
433+
'formtype' => 'TEXT',
434+
'default' => $_csrf_value,
435+
'value' => $_csrf_value
436+
);
437+
$record['_csrf_id'] = $_csrf_id;
438+
$record['_csrf_key'] = $_csrf_value;
439+
/* CSRF PROTECTION */
440+
417441
$new_record = array();
418442
if($action == 'EDIT') {
419443
$record = $this->decode($record, $tab);
@@ -669,8 +693,46 @@ function getHTML($record, $tab, $action = 'NEW') {
669693
*/
670694
protected function _encode($record, $tab, $dbencode = true, $api = false) {
671695
global $app;
672-
if($api == true) $fields = &$this->formDef['fields'];
673-
else $fields = &$this->formDef['tabs'][$tab]['fields'];
696+
if($api == true) {
697+
$fields = &$this->formDef['fields'];
698+
} else {
699+
$fields = &$this->formDef['tabs'][$tab]['fields'];
700+
/* CSRF PROTECTION */
701+
if(isset($_POST) && is_array($_POST)) {
702+
$_csrf_valid = false;
703+
if(isset($_POST['_csrf_id']) && isset($_POST['_csrf_key'])) {
704+
$_csrf_id = trim($_POST['_csrf_id']);
705+
$_csrf_key = trim($_POST['_csrf_key']);
706+
if(isset($_SESSION['_csrf']) && isset($_SESSION['_csrf'][$_csrf_id]) && isset($_SESSION['_csrf_timeout']) && isset($_SESSION['_csrf_timeout'][$_csrf_id])) {
707+
if($_SESSION['_csrf'][$_csrf_id] === $_csrf_key && $_SESSION['_csrf_timeout'] >= time()) $_csrf_valid = true;
708+
}
709+
}
710+
if($_csrf_valid !== true) {
711+
$app->log('CSRF attempt blocked. Referer: ' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'unknown'), LOGLEVEL_WARN);
712+
unset($_POST);
713+
unset($record);
714+
}
715+
$_SESSION['_csrf'][$_csrf_id] = ' ';
716+
$_SESSION['_csrf_timeout'][$_csrf_id] = ' ';
717+
unset($_SESSION['_csrf'][$_csrf_id]);
718+
unset($_SESSION['_csrf_timeout'][$_csrf_id]);
719+
720+
if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) {
721+
$to_unset = array();
722+
foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) {
723+
if($timeout < time()) $to_unset[] = $_csrf_id;
724+
}
725+
foreach($to_unset as $_csrf_id) {
726+
unset($_SESSION['_csrf'][$_csrf_id]);
727+
unset($_SESSION['_csrf_timeout'][$_csrf_id]);
728+
}
729+
unset($to_unset);
730+
}
731+
}
732+
/* CSRF PROTECTION */
733+
}
734+
735+
$new_record = array();
674736
if(is_array($record)) {
675737
foreach($fields as $key => $field) {
676738

interface/web/themes/default/templates/tabbed_form.tpl.htm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ <h1><tmpl_var name="form_hint"></h1>
3636
</div>
3737
</div>
3838

39+
<input type="hidden" name="_csrf_id" value="{tmpl_var name='_csrf_id'}" />
40+
<input type="hidden" name="_csrf_key" value="{tmpl_var name='_csrf_key'}" />
3941
<input type="hidden" name="next_tab" value="">
4042
<input type="hidden" name="phpsessid" value="{tmpl_var name='phpsessid'}">
4143
</div>
42-
43-

0 commit comments

Comments
 (0)