diff --git a/interface/lib/classes/tform.inc.php b/interface/lib/classes/tform.inc.php index 452230414a14edf37ee8e4125e764b2c47c637c2..d0bb7d128f26bb5697e0ee7dbe5c5c66a9971e85 100644 --- a/interface/lib/classes/tform.inc.php +++ b/interface/lib/classes/tform.inc.php @@ -157,7 +157,6 @@ class tform { return true; } - /** * Converts the data in the array to human readable format * Datatype conversion e.g. to show the data in lists @@ -384,7 +383,31 @@ class tform { if(!is_array($this->formDef)) $app->error("No form definition found."); if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab)."); - + + /* CSRF PROTECTION */ + // generate csrf protection id and key + $_csrf_id = uniqid($this->formDef['name'] . '_'); + $_csrf_value = sha1(uniqid(microtime(true), true)); + if(!isset($_SESSION['_csrf'])) $_SESSION['_csrf'] = array(); + if(!isset($_SESSION['_csrf_timeout'])) $_SESSION['_csrf_timeout'] = array(); + $_SESSION['_csrf'][$_csrf_id] = $_csrf_value; + $_SESSION['_csrf_timeout'][$_csrf_id] = time() + 3600; // timeout hash in 1 hour + $this->formDef['tabs'][$tab]['fields']['_csrf_id'] = array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => $_csrf_id, + 'value' => $_csrf_id + ); + $this->formDef['tabs'][$tab]['fields']['_csrf_key'] = array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => $_csrf_value, + 'value' => $_csrf_value + ); + $record['_csrf_id'] = $_csrf_id; + $record['_csrf_key'] = $_csrf_value; + /* CSRF PROTECTION */ + $new_record = array(); if($action == 'EDIT') { $record = $this->decode($record, $tab); @@ -644,7 +667,46 @@ class tform { if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab is empty or does not exist (TAB: $tab)."); //$this->errorMessage = ''; - + + /* CSRF PROTECTION */ + if(isset($_POST) && is_array($_POST)) { + $_csrf_valid = false; + if(isset($_POST['_csrf_id']) && isset($_POST['_csrf_key'])) { + $_csrf_id = trim($_POST['_csrf_id']); + $_csrf_key = trim($_POST['_csrf_key']); + if(isset($_SESSION['_csrf']) && isset($_SESSION['_csrf'][$_csrf_id]) && isset($_SESSION['_csrf_timeout']) && isset($_SESSION['_csrf_timeout'][$_csrf_id])) { + if($_SESSION['_csrf'][$_csrf_id] === $_csrf_key && $_SESSION['_csrf_timeout'] >= time()) $_csrf_valid = true; + } + } + if($_csrf_valid !== true) { + $app->log('CSRF attempt blocked. Referer: ' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'unknown'), LOGLEVEL_WARN); + $errmsg = 'err_csrf_attempt_blocked'; + $this->errorMessage .= ($api == true ? $errmsg : $this->wordbook[$errmsg]."<br />") . "\r\n"; + unset($_POST); + unset($record); + } + $_SESSION['_csrf'][$_csrf_id] = null; + $_SESSION['_csrf_timeout'][$_csrf_id] = null; + unset($_SESSION['_csrf'][$_csrf_id]); + unset($_SESSION['_csrf_timeout'][$_csrf_id]); + + if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) { + $to_unset = array(); + foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) { + if($timeout < time()) $to_unset[] = $_csrf_id; + } + foreach($to_unset as $_csrf_id) { + $_SESSION['_csrf'][$_csrf_id] = null; + $_SESSION['_csrf_timeout'][$_csrf_id] = null; + unset($_SESSION['_csrf'][$_csrf_id]); + unset($_SESSION['_csrf_timeout'][$_csrf_id]); + } + unset($to_unset); + } + } + /* CSRF PROTECTION */ + + $new_record = array(); if(is_array($record)) { foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) { diff --git a/interface/lib/lang/de.lng b/interface/lib/lang/de.lng index 735b1da09cf850006c07e65ff7f4ab1a44d5c2ce..7f510a14f258ae390676e3f9451ab373201c9603 100644 --- a/interface/lib/lang/de.lng +++ b/interface/lib/lang/de.lng @@ -42,6 +42,7 @@ $wb['top_menu_domain'] = 'Domains'; $wb['top_menu_dashboard'] = 'Übersicht'; $wb['latest_news_txt'] = 'Neuigkeiten'; $wb['top_menu_vm'] = 'vServer'; +$wb['err_csrf_attempt_blocked'] = 'CSRF-Versuch blockiert.'; $wb['daynamesmin_su'] = 'So'; $wb['daynamesmin_mo'] = 'Mo'; $wb['daynamesmin_tu'] = 'Di'; diff --git a/interface/lib/lang/en.lng b/interface/lib/lang/en.lng index c89c97a7ccaed04036a54541fcb431b2ef608ce2..5a7efeff0af95a813a71e19b113f4dbf6e7389bc 100644 --- a/interface/lib/lang/en.lng +++ b/interface/lib/lang/en.lng @@ -131,6 +131,7 @@ $wb['datalog_status_d_web_folder'] = 'Delete folder protection'; $wb['datalog_status_i_web_folder_user'] = 'Create folder protection user'; $wb['datalog_status_u_web_folder_user'] = 'Update folder protection user'; $wb['datalog_status_d_web_folder_user'] = 'Delete folder protection user'; +$wb['err_csrf_attempt_blocked'] = 'CSRF attempt blocked.'; $wb['login_as_txt'] = 'Log in as'; $wb["no_domain_perm"] = 'You have no permission for this domain.'; $wb["no_destination_perm"] = 'You have no permission for this destination.'; diff --git a/interface/web/monitor/show_sys_state.php b/interface/web/monitor/show_sys_state.php index 93d1f95971655857e65a5c8bc22975cea395ce43..23c32fb62c1484a43ef2fb6c8d20571e65c67c8a 100644 --- a/interface/web/monitor/show_sys_state.php +++ b/interface/web/monitor/show_sys_state.php @@ -191,7 +191,7 @@ function _getServerState($serverId, $serverName) { /* * Get all monitoring-data from the server and process then */ - $records = $app->db->queryAllRecords("SELECT DISTINCT type, data FROM monitor_data WHERE server_id = " . $serverId); + $records = $app->db->queryAllRecords("SELECT DISTINCT type, data FROM monitor_data WHERE server_id = " . intval($serverId)); $osData = null; $veInfo = null; $ispcData = null; @@ -320,7 +320,7 @@ function _processDbState($type, $serverId, $serverState, $messages) { * state */ // get the State from the DB - $record = $app->db->queryOneRecord("SELECT state FROM monitor_data WHERE type = '" . $type . "' and server_id = " . $serverId . " order by created desc"); + $record = $app->db->queryOneRecord("SELECT state FROM monitor_data WHERE type = '" . $app->db->quote($type) . "' and server_id = " . intval($serverId) . " order by created desc"); // change the new state to the highest state /* diff --git a/interface/web/themes/default/templates/tabbed_form.tpl.htm b/interface/web/themes/default/templates/tabbed_form.tpl.htm index 08002d5282c918377fac880c45db6ba926bbc5e6..64f2a335be2077991c6bc6ed4c170ebd62cd232b 100644 --- a/interface/web/themes/default/templates/tabbed_form.tpl.htm +++ b/interface/web/themes/default/templates/tabbed_form.tpl.htm @@ -23,5 +23,7 @@ <tmpl_dyninclude name="content_tpl"> </div> +<input type="hidden" name="_csrf_id" value="{tmpl_var name='_csrf_id'}" /> +<input type="hidden" name="_csrf_key" value="{tmpl_var name='_csrf_key'}" /> <input type="hidden" name="next_tab" value=""> <input type="hidden" name="phpsessid" value="{tmpl_var name='phpsessid'}"> \ No newline at end of file