Ankündigung

Einklappen
Keine Ankündigung bisher.

ab PHP 7.1 Login-Problem

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • ab PHP 7.1 Login-Problem

    Guten Tag Allerseits,

    Folgender Code-Teil funktioniert von PHP 5.4 bis PHP 7.0 ohne Probleme, allerdings ab PHP 7.1 nicht mehr.

    PHP-Code:
    <?php
    define
    ('BASE_FOLDER'__DIR__ .'/..');
    include(
    BASE_FOLDER '/global.inc.php');
    include(
    BASE_FOLDER '/modules/admin/functions.inc.php');
    include(
    CONFIGCACHE_FILE_ADMIN);
    // include messages
    $i18n I18n::getInstance(Lib::Config('supported_languages'));
    if (isset(
    $_GET['lang'])) {
        
    $i18n->setCurrentLanguage($_GET['lang']);
    }
    include(
    sprintf(CONFIGCACHE_ADMINMESSAGES$i18n->getCurrentLanguage()));
    $errors = [];
    $inputUser = (isset($_POST['inputUser'])) ? $_POST['inputUser'] : FALSE;
    $inputPassword = (isset($_POST['inputPassword'])) ? $_POST['inputPassword'] : FALSE;
    $forwarded = (isset($_GET['forwarded']) && $_GET['forwarded'] == 1) ? TRUE FALSE;
    $loggedout = (isset($_GET['loggedout']) && $_GET['loggedout'] == 1) ? TRUE FALSE;
    $newpwd = (isset($_GET['newpwd']) && $_GET['newpwd'] == 1) ? TRUE FALSE;
    // process form
    if ($inputUser or $inputPassword) {
        if (!
    $inputUser) {
            
    $errors['inputUser'] = Lib::Message('login_error_nousername');
        }
        if (!
    $inputPassword) {
            
    $errors['inputPassword'] = Lib::Message('login_error_nopassword');
        }
        if (
    count($errors) == 0) {
            
    // correct Pwd?
            
    $columns = array('id''passwort''passwort_salt''passwort_neu''name');
            
    $fromTable $conf['db_prefix'] .'_admin';
            
    $whereCondition 'name = \'%s\'';
            
    $parameters $inputUser;
            
    $result $db->querySelect($columns$fromTable$whereCondition$parameters);
            if(
    $result->num_rows 1) {
                
    $errors['inputUser'] = Lib::Message('login_error_unknownusername');
            } else {
                
    $admin $result->fetch_array();
                
    $hashedPw SecurityUtil::hashPassword($inputPassword$admin['passwort_salt']);
                
    $hashedPwo SecurityUtil::hashPassword($inputPassword,'');
                if (
    $admin['passwort'] == $hashedPw || $admin['passwort_neu'] == $hashedPw || $admin['passwort'] == $hashedPwo) {
                    
    session_start();
                    
    $_SESSION['valid'] = 1;
                    
    $_SESSION['userid'] = $admin['id'];
                    
    // update new PW
                    
    if ($admin['passwort_neu'] == $hashedPw) {
                        
    $columns = array('passwort' => $hashedPw'passwort_neu_angefordert' => 0'passwort_neu' => '');
                        
    $fromTable $conf['db_prefix'] .'_admin';
                        
    $whereCondition 'id = %d';
                        
    $parameter $admin['id'];
                        
    $db->queryUpdate($columns$fromTable$whereCondition$parameter);
                    }
                    
    // write log
                    
    if ($admin['name']) {
                        
    $ip getenv('REMOTE_ADDR');
                        
    $content $admin['name'] .', '$ip .', 'date('d.m.y - H:i:s');
                        
    $content .= "\n";
                        
    $datei '../generated/adminlog.php';
                        
    $fp fopen($datei'a+');
                        if (
    filesize($datei)) {
                            
    $inhalt fread($fpfilesize($datei));
                        } else {
                            
    $inhalt '';
                        }
                        
    $inhalt .= $content;
                        
    fwrite($fp$content);
                        
    fclose($fp);
                    }
                    
    header('location: index.php');
                } else {
                    
    $errors['inputPassword'] = Lib::Message('login_error_invalidpassword');
                    
    sleep(5);
                }
            }
            
    $result->free();
        }
    }
    header('Content-type: text/html; charset=utf-8');
    ?>
    <!DOCTYPE html>
    <html lang='de'>
        <head>
            <title><?php echo Lib::Message('login_title');?></title>
            <link href='../modules/admin/admincenter.css' rel='stylesheet' media='screen'>
            <link rel='shortcut icon' type='image/x-icon' href='../favicon.ico' />
            <meta charset='UTF-8'>
            <style type='text/css'>
                body { padding-top: 100px; padding-bottom: 40px; }
            </style>
        </head>
        <body>
            <div class='container'>
                <h1><?php echo Lib::Message('login_title');?></h1>
                <?php
                    
    if ($forwarded) {
                        echo 
    Lib::WarningMessage(Lib::Message('login_alert_accessdenied_title'), Lib::Message('login_alert_accessdenied_content'));
                    } else if (
    $loggedout) {
                        echo 
    Lib::SuccessMessage(Lib::Message('login_alert_logoutsuccess_title'), Lib::Message('login_alert_logoutsuccess_content'));
                    } else if (
    $newpwd) {
                        echo 
    Lib::SuccessMessage(Lib::Message('login_alert_sentpassword_title'), Lib::Message('login_alert_sentpassword_content'));
                    } else if (
    count($errors) > 0) {
                        echo 
    Lib::ErrorMessage(Lib::Message('login_alert_error_title'), Lib::Message('login_alert_error_content'));
                    }
                
    ?>
                <p><a href='?lang=de'>Deutsch</a></p>
                <form action='login.php' method='post' class='form-horizontal'>
                    <div class='control-group<?php if (isset($errors['inputUser'])) echo ' error'?>'>
                        <label class='control-label' for='inputUser'><?php echo Lib::Message('login_label_user');?></label>
                        <div class='controls'>
                            <input type='text' name='inputUser' id='inputUser' placeholder='<?php echo Lib::Message('login_label_user');?>' required>
                        </div>
                    </div>
                    <div class='control-group<?php if (isset($errors['inputPassword'])) echo ' error'?>'>
                        <label class='control-label' for='inputPassword'><?php echo Lib::Message('login_label_password');?></label>
                        <div class='controls'>
                            <input type='password' name='inputPassword' id='inputPassword' placeholder='<?php echo Lib::Message('login_label_password');?>'>
                        </div>
                    </div>
                    <div class='control-group'>
                        <div class='controls'>
                              <button type='submit' class='btn'><?php echo Lib::Message('login_button_logon');?></button>
                        </div>
                    </div>
                </form>
                <p><a href='forgot-password.php'><?php echo Lib::Message('login_link_forgotpassword');?></a>
                <hr>
                <footer>
                     <div id="footer">
                         <a href="https://github.com/rolfjoseph/openwebsoccer2017" target="_blank"> <?php readfile('../version.txt'); readfile('../build.txt'); ?>
                    </div>
                </footer>
            </div>
            <script src='../modules/admincenter.js'></script>
        </body>
    </html>
    - Eigenartiger Weise wird das Login zuerst korrekt vollzogen und in die Logdatei geschrieben. Der Header Redirect funktioniert dann jedoch nicht.
    - Die Session wird nun nicht mehr mit 26, sondern mit 32 Zeichen gespeichert.

    Hat sich bei den Session unter PHP 7.1 noch etwas getan ?

    In einer Klasse ist folgende Funktion:

    PHP-Code:
    static function isAdminLoggedIn() {
            
    // prevent session hijacking
            
    if (isset($_SESSION['HTTP_USER_AGENT'])) {
                if (
    $_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) {
                    
    self::logoutAdmin();
                    return 
    FALSE;
                }
            } else {
                
    $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
            }
            return (isset(
    $_SESSION['valid']) && $_SESSION['valid']);
        } 
    Die dann im folgenden Code genutzt wird:

    PHP-Code:
    // log in user
    if (SecurityUtil::isAdminLoggedIn()) {
        
    $columns '*';
        
    $fromTable $conf['db_prefix'] .'_admin';
        
    $whereCondition 'id = %d';
        
    $parameters $_SESSION['userid'];
        
    $result $db->querySelect($columns$fromTable$whereCondition$parameters);
        
    $admin $result->fetch_array();
        
    $result->free();
    } else {
        
    header('location: login.php?forwarded=1');
        exit;

    Das vordergründige Problem scheint die static function isAdminLoggedIn() zu sein.
    Dort wird anscheinend der Wert von (isset($_SESSION['valid']) && $_SESSION['valid']) nicht zurück geliefert.
    Kann PHP ab 7.1 nicht mehr die Werte auslesen, obwohl $_SESSION['valid'] = 1; gesetzt ist ?

    Leider bin ich nicht dahinter gekommen, was ab PHP 7.1 dort geändert wurde.

  • #2
    Warum schaust du nicht einfach, was in $_SESSION drin steht?

    Kommentar


    • #3
      ich hab es nur kurz überflogen. Außer die Frage von hellbringer. Könnte auch noch helfen ob du irgend eine Warning / Error bekommst. Im übrigen hat sich zwischen PHP 7 und 7.1 folgendes bzgl Session geändert (Zitat aus der Patchnote)

      Session ID generation without hashing

      Session IDs will no longer be hashed upon generation. With this change brings about the removal of the following four ini settings:
      • session.entropy_file
      • session.entropy_length
      • session.hash_function
      • session.hash_bits_per_character

      And the addition of the following two ini settings:
      • session.sid_length - defines the length of the session ID, defaulting to 32 characters for backwards compatibility)
      • session.sid_bits_per_character - defines the number of bits to be stored per character (i.e. increases the range of characters that can be used in the session ID), defaulting to 4 for backwards compatibility

      Kommentar


      • #4
        Nach weiteren Test:

        bis PHP 7.0 waren die Sessions kein Problem, auch wenn ein Fehler wie session.save_path nicht gefunden auftrat.( Wurde anscheinend automatisch durch PHP korrigiert )
        Ab PHP 7.1 bewirkt dieser Fehler allerdings, das zwar ein Cookie vorhanden ist, aber die Session nicht angelegt wird.

        Solution:

        // register own session handler
        $handler = new DbSessionManager($db, $website);
        session_set_save_handler(
        array($handler, 'open'),
        array($handler, 'close'),
        array($handler, 'read'),
        array($handler, 'write'),
        array($handler, 'destroy'),
        array($handler, 'gc')
        );
        ini_set('session.save_handler', 'files');
        ini_set('session.save_path', session_save_path());

        session_start();

        Durch diese zwei Zeilen funktioniert der Login sowohl im Frontend und Backend wieder, sowohl in der Windows- und Webspaceumgebung.
        Ich weis nicht, ob das von den PHP-Leuten so gewollt war, das man nun des Session-Pfad explizit angeben muss.

        Eigentlich müsste jetzt der Beitrag umbenannt werden in: Solution für Session-Problem ab PHP 7.1

        Kommentar


        • #5
          Das ist keine Lösung, dass ist wild zusammen kopierter Code und dazu noch widersprüchlich. Ich könnte nichtmal erklären was PHP hier schlussendlich macht.

          Kommentar

          Lädt...
          X