Skip to content

Commit 582cbf7

Browse files
author
Marius Cramer
committed
- added csrf protection to tforms
- possible sql injection in monitor sys_state
1 parent e644c02 commit 582cbf7

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

interface/lib/classes/tform.inc.php

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ function loadFormDef($file, $module = '') {
157157
return true;
158158
}
159159

160-
161160
/**
162161
* Converts the data in the array to human readable format
163162
* Datatype conversion e.g. to show the data in lists
@@ -384,7 +383,31 @@ function getHTML($record, $tab, $action = 'NEW') {
384383

385384
if(!is_array($this->formDef)) $app->error("No form definition found.");
386385
if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
387-
386+
387+
/* CSRF PROTECTION */
388+
// generate csrf protection id and key
389+
$_csrf_id = uniqid($this->formDef['name'] . '_');
390+
$_csrf_value = sha1(uniqid(microtime(true), true));
391+
if(!isset($_SESSION['_csrf'])) $_SESSION['_csrf'] = array();
392+
if(!isset($_SESSION['_csrf_timeout'])) $_SESSION['_csrf_timeout'] = array();
393+
$_SESSION['_csrf'][$_csrf_id] = $_csrf_value;
394+
$_SESSION['_csrf_timeout'][$_csrf_id] = time() + 3600; // timeout hash in 1 hour
395+
$this->formDef['tabs'][$tab]['fields']['_csrf_id'] = array(
396+
'datatype' => 'VARCHAR',
397+
'formtype' => 'TEXT',
398+
'default' => $_csrf_id,
399+
'value' => $_csrf_id
400+
);
401+
$this->formDef['tabs'][$tab]['fields']['_csrf_key'] = array(
402+
'datatype' => 'VARCHAR',
403+
'formtype' => 'TEXT',
404+
'default' => $_csrf_value,
405+
'value' => $_csrf_value
406+
);
407+
$record['_csrf_id'] = $_csrf_id;
408+
$record['_csrf_key'] = $_csrf_value;
409+
/* CSRF PROTECTION */
410+
388411
$new_record = array();
389412
if($action == 'EDIT') {
390413
$record = $this->decode($record, $tab);
@@ -644,7 +667,42 @@ function encode($record, $tab, $dbencode = true) {
644667

645668
if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab is empty or does not exist (TAB: $tab).");
646669
//$this->errorMessage = '';
647-
670+
671+
/* CSRF PROTECTION */
672+
if(isset($_POST) && is_array($_POST)) {
673+
$_csrf_valid = false;
674+
if(isset($_POST['_csrf_id']) && isset($_POST['_csrf_key'])) {
675+
$_csrf_id = trim($_POST['_csrf_id']);
676+
$_csrf_key = trim($_POST['_csrf_key']);
677+
if(isset($_SESSION['_csrf']) && isset($_SESSION['_csrf'][$_csrf_id]) && isset($_SESSION['_csrf_timeout']) && isset($_SESSION['_csrf_timeout'][$_csrf_id])) {
678+
if($_SESSION['_csrf'][$_csrf_id] === $_csrf_key && $_SESSION['_csrf_timeout'] >= time()) $_csrf_valid = true;
679+
}
680+
}
681+
if($_csrf_valid !== true) {
682+
$app->log('CSRF attempt blocked. Referer: ' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'unknown'), LOGLEVEL_WARN);
683+
unset($_POST);
684+
unset($record);
685+
}
686+
$_SESSION['_csrf'][$_csrf_id] = ' ';
687+
$_SESSION['_csrf_timeout'][$_csrf_id] = ' ';
688+
unset($_SESSION['_csrf'][$_csrf_id]);
689+
unset($_SESSION['_csrf_timeout'][$_csrf_id]);
690+
691+
if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) {
692+
$to_unset = array();
693+
foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) {
694+
if($timeout < time()) $to_unset[] = $_csrf_id;
695+
}
696+
foreach($to_unset as $_csrf_id) {
697+
unset($_SESSION['_csrf'][$_csrf_id]);
698+
unset($_SESSION['_csrf_timeout'][$_csrf_id]);
699+
}
700+
unset($to_unset);
701+
}
702+
}
703+
/* CSRF PROTECTION */
704+
705+
$new_record = array();
648706
if(is_array($record)) {
649707
foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
650708

interface/web/monitor/show_sys_state.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ function _getServerState($serverId, $serverName) {
191191
/*
192192
* Get all monitoring-data from the server and process then
193193
*/
194-
$records = $app->db->queryAllRecords("SELECT DISTINCT type, data FROM monitor_data WHERE server_id = " . $serverId);
194+
$records = $app->db->queryAllRecords("SELECT DISTINCT type, data FROM monitor_data WHERE server_id = " . intval($serverId));
195195
$osData = null;
196196
$veInfo = null;
197197
$ispcData = null;
@@ -320,7 +320,7 @@ function _processDbState($type, $serverId, $serverState, $messages) {
320320
* state
321321
*/
322322
// get the State from the DB
323-
$record = $app->db->queryOneRecord("SELECT state FROM monitor_data WHERE type = '" . $type . "' and server_id = " . $serverId . " order by created desc");
323+
$record = $app->db->queryOneRecord("SELECT state FROM monitor_data WHERE type = '" . $app->db->quote($type) . "' and server_id = " . intval($serverId) . " order by created desc");
324324

325325
// change the new state to the highest state
326326
/*

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,7 @@ <h2><tmpl_var name="form_hint"></h2>
2323
<tmpl_dyninclude name="content_tpl">
2424
</div>
2525

26+
<input type="hidden" name="_csrf_id" value="{tmpl_var name='_csrf_id'}" />
27+
<input type="hidden" name="_csrf_key" value="{tmpl_var name='_csrf_key'}" />
2628
<input type="hidden" name="next_tab" value="">
2729
<input type="hidden" name="phpsessid" value="{tmpl_var name='phpsessid'}">

0 commit comments

Comments
 (0)