Marius Cramer
2015-06-03 1e24e990804732a0f6981cd2db7fda2da11b29ed
Merge branch 'master' into 'master'

Master Fixes

See merge request !198
4 files modified
76 ■■■■■ changed files
interface/lib/classes/tform_base.inc.php 70 ●●●●● patch | view | raw | blame | history
interface/lib/lang/de.lng 1 ●●●● patch | view | raw | blame | history
interface/lib/lang/en.lng 1 ●●●● patch | view | raw | blame | history
interface/web/themes/default/templates/tabbed_form.tpl.htm 4 ●●●● patch | view | raw | blame | history
interface/lib/classes/tform_base.inc.php
@@ -414,6 +414,30 @@
        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);
@@ -669,8 +693,50 @@
     */
    protected function _encode($record, $tab, $dbencode = true, $api = false) {
        global $app;
        if($api == true) $fields = &$this->formDef['fields'];
        else $fields = &$this->formDef['tabs'][$tab]['fields'];
        if($api == true) {
            $fields = &$this->formDef['fields'];
        } else {
            $fields = &$this->formDef['tabs'][$tab]['fields'];
            /* 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($fields as $key => $field) {
interface/lib/lang/de.lng
@@ -41,6 +41,7 @@
$wb['top_menu_domain'] = 'Domains';
$wb['top_menu_dashboard'] = 'Übersicht';
$wb['latest_news_txt'] = 'Neuigkeiten';
$wb['err_csrf_attempt_blocked'] = 'CSRF-Versuch blockiert.';
$wb['top_menu_vm'] = 'vServer';
$wb['daynamesmin_su'] = 'So';
$wb['daynamesmin_mo'] = 'Mo';
interface/lib/lang/en.lng
@@ -131,6 +131,7 @@
$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.';
interface/web/themes/default/templates/tabbed_form.tpl.htm
@@ -36,8 +36,8 @@
            </div>
        </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'}">
    </div>