Ankündigung

Einklappen
Keine Ankündigung bisher.

POST-Variable kann nicht an Funktion übergeben werden

Einklappen

Neue Werbung 2019

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

  • POST-Variable kann nicht an Funktion übergeben werden

    Hi zusammen,

    ich verzweifel bald - und das PHP nun wirklich nicht mein Fachgebiet ist, benötige ich nun glaube ich wirklich Hilfe
    Ausgangslage: ich habe eine API und diese wird durch ein kleines Addon abgesichert. Die Absicherung geht so:
    - Benutzername und Passwort werden per POST übertragen
    - Es wird ein Token generiert
    - Wenn Username und Passwort gültig sind und ein korrekt Cookie-Session existiert, wird das Token für gültig erklärt
    - Zugriff OK
    (zumindest hab ich das so verstanden ).

    Die Abfrage für Benutzername und Passwort ist in der Auth-API einfach nur als Hardcoded drin:
    PHP-Code:
    $auth = new PHP_API_AUTH(array(
    'authenticator'=>function($user,$pass){ if ($user=='admin' && $pass=='admin'$_SESSION['user']=$user; }
    )); 
    Das ist natürlich quatsch, also mach ich eine eigene Datenbankabfrage, um den Passwort-Hash eines Users abzurufen.
    Dazu habe ich in der sowieso mit
    PHP-Code:
    require 'auth.php'
    geladenen auth.php (da drin ist die Auth-API) eine Funktion eingebaut, welche die an die Auth.php geschickten POST-Daten abfängt und durch die DB laufen lässt.
    Was zurück kommt speichere ich dann ab:
    PHP-Code:
    $password_hash passworthash(); 
    Soweit so gut: wenn ich an dieser Stelle nun die Variable $password_hash ausgebe, erhalte ich den korrekten Wert, der in der DB steht.
    Nun müsste ich das doch nur noch ganz einfach in der Hardcoded-Zeile korrigieren:

    PHP-Code:
    $auth = new PHP_API_AUTH(array(
    'authenticator'=>function($user,$pass){ if ($user=='admin' && $pass=$password_hash$_SESSION['user']=$user; }
    )); 

    Der gesamte Code sieht dann so aus:
    PHP-Code:
    require 'auth.php';

    $password_hash passworthash();
    $auth = new PHP_API_AUTH(array(
    'authenticator'=>function($user,$pass){ if ($user=='admin' && $pass=$password_hash$_SESSION['user']=$user; }
    ));

    if (
    $auth->executeCommand()) exit(0);
    if (empty(
    $_SESSION['user']) || !$auth->hasValidCsrfToken()) {
    header('HTTP/1.0 401 Unauthorized');
    exit(
    0);

    Nur funktioniert das nicht. Beim Aufruf dort ist $password_hash dann aber leer - somit funktioniert das auch nicht.
    Was mach ich falsch? Und wie krieg ich das hin?
    Quelldaten kann ich falls nötig zur Verfügung stellen.

    Danke im Voraus und Gruss,
    KlyX

  • #2
    Was macht passworthash()? Zeig mal die Funktion. Gibt die auch was zurück? return
    The string "()()" is not palindrom but the String "())(" is.

    Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
    PHP.de Wissenssammlung | Kein Support per PN

    Kommentar


    • #3
      Wie hausi schon sagte aber auch ein:
      PHP-Code:
      'authenticator'=>function($user,$pass) use ($password_hash) { if ($user=='admin' && $pass=$password_hash$_SESSION['user']=$user; } 
      hilft vielleicht.

      Kommentar


      • #4
        Danke für die raschen Antworten
        hausl Also: die Funktion liefert den korrekten Wert zurück - hab ich schon geprüft. Wenn ich direkt nach dem Funktionaufruf die Variable mit echo Ausgebe, wird der korrekte Hash-Wert ausgegeben.

        msp klappt leider nicht - auch so ist der Rückgabewert leider leer.

        Hier mal der komplette Code von der Auth.php zum besseren Verständnis. Meine Funktion habe ich ganz unten eingebaut und ist vom Rest unabhängig. Muss aber in der Auth.php sein, da dort die POST-Daten hingeschickt werden.
        PHP-Code:
        <?php
        //Originalscript ---->
        class PHP_API_AUTH {

            public function 
        __construct($config) {
                
        extract($config);

                
        $verb = isset($verb)?$verb:null;
                
        $path = isset($path)?$path:null;
                
        $username = isset($username)?$username:null;
                
        $password = isset($password)?$password:null;
                
        $token = isset($token)?$token:null;
                
        $authenticator = isset($authenticator)?$authenticator:null;

                
        $method = isset($method)?$method:null;
                
        $request = isset($request)?$request:null;
                
        $post = isset($post)?$post:null;
                
        $origin = isset($origin)?$origin:null;

                
        $time = isset($time)?$time:null;
                
        $leeway = isset($leeway)?$leeway:null;
                
        $ttl = isset($ttl)?$ttl:null;
                
        $algorithm = isset($algorithm)?$algorithm:null;
                
        $secret = isset($secret)?$secret:null;

                
        $allow_origin = isset($allow_origin)?$allow_origin:null;

                
        // defaults
                
        if (!$verb) {
                    
        $verb 'POST';
                }
                if (!
        $path) {
                    
        $path '';
                }
                if (!
        $username) {
                    
        $username 'username';
                }
                if (!
        $password) {
                    
        $password 'password';
                }
                if (!
        $token) {
                    
        $token 'token';
                }

                if (!
        $method) {
                    
        $method $_SERVER['REQUEST_METHOD'];
                }
                if (!
        $request) {
                    
        $request = isset($_SERVER['PATH_INFO'])?$_SERVER['PATH_INFO']:'';
                    if (!
        $request) {
                        
        $request = isset($_SERVER['ORIG_PATH_INFO'])?$_SERVER['ORIG_PATH_INFO']:'';
                    }
                }
                if (!
        $post) {
                    
        $post 'php://input';
                }
                if (!
        $origin) {
                    
        $origin = isset($_SERVER['HTTP_ORIGIN'])?$_SERVER['HTTP_ORIGIN']:'';
                }

                if (!
        $time) {
                    
        $time time();
                }
                if (!
        $leeway) {
                    
        $leeway 5;
                }
                if (!
        $ttl) {
                    
        $ttl 30;
                }
                if (!
        $algorithm) {
                    
        $algorithm 'HS256';
                }

                if (
        $allow_origin===null) {
                    
        $allow_origin '*';
                }

                
        $request trim($request,'/');

                
        $this->settings compact('verb''path''username''password''token''authenticator''method''request''post''origin''time''leeway''ttl''algorithm''secret''allow_origin');
            }


            protected function 
        retrieveInput($post) {
                
        $input = (object)array();
                
        $data trim(file_get_contents($post));
                if (
        strlen($data)>0) {
                    if (
        $data[0]=='{') {
                        
        $input json_decode($data);
                    } else {
                        
        parse_str($data$input);
                        
        $input = (object)$input;
                    }
                }
                return 
        $input;
            }

            protected function 
        generateToken($claims,$time,$ttl,$algorithm,$secret) {
                
        $algorithms = array('HS256'=>'sha256','HS384'=>'sha384','HS512'=>'sha512');
                
        $header = array();
                
        $header['typ']='JWT';
                
        $header['alg']=$algorithm;
                
        $token = array();
                
        $token[0] = rtrim(strtr(base64_encode(json_encode((object)$header)),'+/','-_'),'=');
                
        $claims['iat'] = $time;
                
        $claims['exp'] = $time $ttl;
                
        $token[1] = rtrim(strtr(base64_encode(json_encode((object)$claims)),'+/','-_'),'=');
                if (!isset(
        $algorithms[$algorithm])) return false;
                
        $hmac $algorithms[$algorithm];
                
        $signature hash_hmac($hmac,"$token[0].$token[1]",$secret,true);
                
        $token[2] = rtrim(strtr(base64_encode($signature),'+/','-_'),'=');
                return 
        implode('.',$token);
            }

            protected function 
        getVerifiedClaims($token,$time,$leeway,$ttl,$algorithm,$secret) {
                
        $algorithms = array('HS256'=>'sha256','HS384'=>'sha384','HS512'=>'sha512');
                if (!isset(
        $algorithms[$algorithm])) return false;
                
        $hmac $algorithms[$algorithm];
                
        $token explode('.',$token);
                if (
        count($token)<3) return false;
                
        $header json_decode(base64_decode(strtr($token[0],'-_','+/')),true);
                if (!
        $secret) return false;
                if (
        $header['typ']!='JWT') return false;
                if (
        $header['alg']!=$algorithm) return false;
                
        $signature bin2hex(base64_decode(strtr($token[2],'-_','+/')));
                if (
        $signature!=hash_hmac($hmac,"$token[0].$token[1]",$secret)) return false;
                
        $claims json_decode(base64_decode(strtr($token[1],'-_','+/')),true);
                if (!
        $claims) return false;
                if (isset(
        $claims['nbf']) && $time+$leeway<$claims['nbf']) return false;
                if (isset(
        $claims['iat']) && $time+$leeway<$claims['iat']) return false;
                if (isset(
        $claims['exp']) && $time-$leeway>$claims['exp']) return false;
                if (isset(
        $claims['iat']) && !isset($claims['exp'])) {
                    if (
        $time-$leeway>$claims['iat']+$ttl) return false;
                }
                return 
        $claims;
            }

            protected function 
        allowOrigin($origin,$allowOrigins) {
                if (isset(
        $_SERVER['REQUEST_METHOD'])) {
                    
        header('Access-Control-Allow-Credentials: true');
                    
        header('Access-Control-Expose-Headers: X-XSRF-TOKEN');
                    foreach (
        explode(',',$allowOrigins) as $o) {
                        if (
        preg_match('/^'.str_replace('\*','.*',preg_quote(strtolower(trim($o)))).'$/',$origin)) {
                            
        header('Access-Control-Allow-Origin: '.$origin);
                            break;
                        }
                    }
                }
            }

            protected function 
        headersCommand() {
                
        $headers = array();
                
        $headers[]='Access-Control-Allow-Headers: Content-Type, X-XSRF-TOKEN';
                
        $headers[]='Access-Control-Allow-Methods: OPTIONS, GET, PUT, POST, DELETE, PATCH';
                
        $headers[]='Access-Control-Allow-Credentials: true';
                
        $headers[]='Access-Control-Max-Age: 1728000';
                if (isset(
        $_SERVER['REQUEST_METHOD'])) {
                    foreach (
        $headers as $headerheader($header);
                } else {
                    echo 
        json_encode($headers);
                }
            }

            public function 
        hasValidCsrfToken() {
                
        $csrf = isset($_SESSION['csrf'])?$_SESSION['csrf']:false;
                if (!
        $csrf) return false;
                
        $get = isset($_GET['csrf'])?$_GET['csrf']:false;
                
        $header = isset($_SERVER['HTTP_X_XSRF_TOKEN'])?$_SERVER['HTTP_X_XSRF_TOKEN']:false;
                return (
        $get == $csrf) || ($header == $csrf);
            }

            public function 
        executeCommand() {
                
        extract($this->settings);
                if (
        $origin) {
                    
        $this->allowOrigin($origin,$allow_origin);
                }
                if (
        $method=='OPTIONS') {
                    
        $this->headersCommand();
                    return 
        true;
                }
                
        $no_session $authenticator && $secret;
                if (!
        $no_session) {
                    
        ini_set('session.cookie_httponly'1);
                    
        session_start();
                    if (!isset(
        $_SESSION['csrf'])) {
                        if (
        function_exists('random_int')) $_SESSION['csrf'] = 'N'.random_int(0,PHP_INT_MAX);
                        else 
        $_SESSION['csrf'] = 'N'.rand(0,PHP_INT_MAX);
                    }
                }
                if (
        $method==$verb && trim($path,'/')==$request) {
                    
        $input $this->retrieveInput($post);    
                    if (
        $authenticator && isset($input->$username) && isset($input->$password)) {
                        
        $authenticator($input->$username,$input->$password);

                        if (
        $no_session) {
                            echo 
        json_encode($this->generateToken($_SESSION,$time,$ttl,$algorithm,$secret));
                        } else {
                            
        session_regenerate_id();
                            
        setcookie('XSRF-TOKEN',$_SESSION['csrf'],0,'/');
                            
        header('X-XSRF-TOKEN: '.$_SESSION['csrf']);
                            echo 
        json_encode($_SESSION['csrf']);
                        }
                    } elseif (
        $secret && isset($input->$token)) {
                        
        $claims $this->getVerifiedClaims($input->$token,$time,$leeway,$ttl,$algorithm,$secret);
                        if (
        $claims) {
                            foreach (
        $claims as $key=>$value) {
                                
        $_SESSION[$key] = $value;
                            }
                            
        session_regenerate_id();
                            
        setcookie('XSRF-TOKEN',$_SESSION['csrf'],0,'/');
                            
        header('X-XSRF-TOKEN: '.$_SESSION['csrf']);
                            echo 
        json_encode($_SESSION['csrf']);
                        }
                    } else {
                        if (!
        $no_session) {
                            
        session_destroy();
                        }
                    }
                    return 
        true;
                }
                return 
        false;
            }

        }
        //chgeiser --> Hier wird die DB-Abfrage zur Bestimmung des User-Hashs durchgeführt
        function passworthash()
                    {
                    
        $benutzername $_POST["username"];
                    
        //$input = $this->retrieveInput($post);    
                    
        include 'db_connect.php';
                    
        $sql_statement "SELECT * FROM users WHERE username='" $benutzername "'";
                    
        $statement=$pdo->prepare($sql_statement);
                    
        $statement->execute();
                    while(
        $row $statement->fetch()) {
                        
        $password_hash $row['password'];
                    }
                        return 
        $password_hash;
                    }
        //Ende Anpassung chGeiser

        Kommentar


        • #5
          Korrektur - irgendwie läuft das jetzt noch komischer.
          Hab zwei Dinge ausprobiert:
          PHP-Code:
          $auth = new PHP_API_AUTH(array(
          'authenticator'=>function($user,$pass) use ($password_hash) { if ($user=='admin' && $pass==$password_hash$_SESSION['user']=$user; }
          )); 
          --> in dieser Variante lässt er mich nie durch - auch nicht mit einem leeren Passwortstring (= $pass wäre leer, so wie vorhin)

          PHP-Code:
          $auth = new PHP_API_AUTH(array(
          'authenticator'=>function($user,$pass) use ($password_hash) { if ($user=='admin' && $pass=$password_hash$_SESSION['user']=$user; }
          )); 
          In dieser Variante lässt er nun alles durch was reinkommt... häää??

          Kommentar


          • #6
            PHP-Code:
            $benutzername $_POST["username"];
                        
            //$input = $this->retrieveInput($post);    
                        
            include 'db_connect.php';
                        
            $sql_statement "SELECT * FROM users WHERE username='" $benutzername "'"
            Du bist aber ganz schön mutig => https://de.wikipedia.org/wiki/SQL-Injection
            Die While kannst du dir auch sparen, wirst hoffentlich nur eine Zeile haben.


            Dein Plan wird so nicht aufgehen. Du musst eine Funktion für die Authentication ordentlich implementieren, diese bekommt dann username + passwort und sollte die Validierung übernehmen. Du kannst das so nicht hineingeben ohne die Klasse oben zu ändern. Verstehst du?

            Kommentar


            • #7
              PHP-Code:
               $pass=$password_hash 

              Kommentar


              • #8
                msp Thema SQL-Injection... ist mir bewusst. War nur mal eben dahingeschmiert, nachdem ich seit 3 Stunden versucht habe, das irgendwie hinzukriegen Hab das jetzt aber korrigiert.
                Besser so?
                PHP-Code:
                function passworthash()
                            {
                            
                $benutzername $_POST["username"];
                            include 
                'db_connect.php';
                            
                $statement=$pdo->prepare("SELECT * FROM users WHERE username= ?");
                            
                $statement->execute(array ($benutzername));
                            while(
                $row $statement->fetch()) {
                                
                $password_hash $row['password'];
                            }
                                return 
                $password_hash;
                            } 
                Thema Funktion: das habe ich beinahe befürchtet
                Nur: - zitiere Eingangspost:
                und da PHP nun wirklich nicht mein Fachgebiet ist
                - habe ich ehrlich gesagt keinen blassen Dunst, wie ich das irgendwie machen muss und kann
                *seufz*

                Kommentar


                • #9
                  Eine Anmerkung zu Deinem Code:

                  Der Code im Konstruktor ist total krank oder?

                  Aus welchen Grund das extract und am Ende das compact? Das ist vollkommen nutzlos und erzeugt unnötigen Overhead. Arbeite mit dem Array und gut ist.

                  Kommentar


                  • #10
                    Messier 1001 der Code ist nicht von mir - siehe Originalpost. Ist teil einer API die ich benutze Daher auch mein Problem das beschrieben Thema korrekt einzubinden. Ich programmiere in VB und versuche nur die Datenbankabfragen in PHP auszulagern und mit JSON abzufragen, um keine Passwörter zu Datenbanken in VB zu haben Das klappt auch gut. Nur muss ich jetzt noch die PHP-API absichern, womit wir wieder beim Grund für mein Posting sind

                    Kommentar


                    • #11
                      Hi zusammen,

                      aaaalso - nachdem ich den Code jetzt nochmal lange und innig hinterfragt hab (um rauszufinden wie er funktioniert), bin ich auf den Trichter gekommen, dass das user $password_hash sehr wohl funktionieren muss. Hab ich gleich noch getestet, indem ich mir die Werte von $pass und $password_hash innterhab der Funktion habe ausgeben lassen. Ist identisch.
                      Ebenso sollte $pass==$password_hash sein und nicht nur "=" (hab das nochmal geprüft).

                      Nachdem also der Vergleich wohl funktioniert, habe ich die Lösung des Problems mal woanders gesucht.
                      Schlussendlich habe ich festgstellt, dass ich wohl den Hash-Wert nicht korrekt Encodiere. Und da der Hash-Wert Sonderzeichen enthält... klappt es nicht.
                      Ein Hash-Wert ohne Sonderzeichen funktioniert einwandfrei Muss also nur das Codierungsproblem in VB lösen und gut ists

                      Danke!
                      Gruss,
                      KlyX

                      Kommentar


                      • #12
                        Du kannst auch in PHP das Zeichenkodierungsproblem lösen. PHP stellt dazu einige Funktionen bereit.
                        iconv()
                        mb_convert_encoding()
                        von VB zu PHP dann natürlich wieder der umgekehrte Weg winows1252 -> utf-8, wenn dein Script utf-8 gespeichert ist.

                        Kommentar

                        Lädt...
                        X