2014-02-25 8 views
7

Ich bin ein Login-Skript mit einem Brute-Force-Checker, die, wenn ausgelöst, zeigt reCAPTCHA. Das Problem, das ich habe, ist, dass das Login-Skript ausgeführt wird, wenn der richtige Benutzername/Passwort/Captcha-Antwort eingegeben wird, aber nicht, bis der Großteil des Seiteninhalts geladen ist (dies geschieht, nachdem das Formular abgeschickt wurde). Das Ergebnis ist, dass ich F5 drücken muss, um die Seite zu aktualisieren und die Formulardaten erneut zu übermitteln, damit die Sitzung aktiv wird, wenn die Seite geladen wird. JetztPHP Verwenden Sie reCAPTCHA, wenn Brute-Force-Versuch erkannt wird

, das Problem, das ich habe, ist, dass, sobald das Formular abgeschickt wird (wenn es ein CAPTCHA erfordert, das ist), wird die Sitzung nicht gestartet, bis index.php zu

bekommt
else { 
     $captchaResponse = 1; 
     $auth = Auth::verifyPass($userName,$password,$captchaResponse); 
    } 

Ich bin ratlos, wie ich das reorganisieren kann, so dass die Sitzung weit vorher gestartet wird. Irgendwelche Ideen?

  1. Der erste Teil ist die Seite index.php, die den Code enthält, der ausgelöst wird, wenn ein Brute-Force-Versuch erkannt wird. Dieser Teil des Codes beginnt mit dem bedingten if ($ auth === "bruteForce") Dieser Code zeigt reCAPTCHA an und soll den Benutzernamen, das Passwort und den reCAPTCHA-Response-Code (0-inkorrekte Antwort, 1-korrekte Antwort) zurück zu senden die Login-Funktion. Diese

    <?php 
        include('includes/header.php'); 
        spl_autoload_register(function ($class){ 
         include 'includes/class.' . $class . '.php'; 
        }); 
        if(null !==(filter_input(INPUT_POST,'userName'))){$userName = filter_input(INPUT_POST,'userName');} 
        if(null !==(filter_input(INPUT_POST,'password'))){$password = filter_input(INPUT_POST,'password');} 
    
        if(isset($userName)&& isset($password)){ 
         $auth = Auth::verifyPass($userName,$password); 
        } 
    
        if(isset($_GET['logout']) && $_GET['logout'] == true){ 
         session_start(); 
         session_destroy(); 
         setcookie ("PHPSESSID", "", time() - 3600, "/"); 
         header("Location: index.php"); 
        } 
        if(Auth::checkLoggedIn() === true){ 
         if(session_id() !== ''){echo 'Session ID is not blank<br />';} 
         echo '<a href="index.php?logout=true">Logout</a><br />'; 
         echo 'Welcome! This is protected content!' . "<br />"; 
        } 
        if(!Auth::checkLoggedIn()) : 
    ?> 
    <h1>Sign In</h1> 
    <?php if(isset($userName) && isset($password)){if($auth === "invalidPassword"){echo '<span class="error">Invalid username or password</span>';}} ?> 
         <form name="login" method="post" action="index.php" id="loginForm"> 
          <ul> 
           <li> 
            <input placeholder="Username" type="text" name="userName" id="userName" class="login" /> 
           </li> 
           <li> 
            <input placeholder="Password" type="password" name="password" id="password" class="login" /> 
           </li> 
           <?php 
            if(isset($userName) && isset($password)){ 
             echo $auth . "<br />"; 
             if($auth === "bruteForce"){ 
               echo $auth; 
               require_once('includes/recaptchalib.php'); 
    
               // Get a key from https://www.google.com/recaptcha/admin/create 
               $publickey = "xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 
               $privatekey = "xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 
               $resp = null; 
               $error = null; 
               if(isset($_POST["recaptcha_response_field"])){ 
                 $resp = recaptcha_check_answer ($privatekey, 
                         $_SERVER["REMOTE_ADDR"], 
                         $_POST["recaptcha_challenge_field"], 
                         $_POST["recaptcha_response_field"]); 
    
                 if ($resp->is_valid) { 
                  Auth::checkLoggedIn(); 
                   $auth = Auth::verifyPass($userName,$password,1); 
                 } else { 
                   $auth = Auth::verifyPass($userName,$password,0); 
                   //$captchaResponse = 2; 
                 } 
               } 
               echo recaptcha_get_html($publickey, $error); 
               if($auth === "invalidCaptcha"){ 
                echo "Invalid Captcha Response. Please try again."; 
               } 
            } 
            } 
            if(isset($auth)){echo $auth;} 
           ?> 
           <div class="clearAll">&nbsp;</div> 
           <li id="submit"> 
            <input type="submit" value="Login" id="loginBtn" class="login" /> 
           </li> 
           <li id="reset"> 
            <input type="reset" value="Reset" id="resetBtn" class="login" /> 
           </li> 
          </ul> 
         </form> 
        <div class="clearAll">&nbsp;</div> 
        <h1>New User?</h1> 
        <p><a href="register.php">Sign Up!</a></p> 
        <?php endif; ?> 
        <div class="clearAll">&nbsp;</div> 
        <?php include('includes/footer.php'); ?> 
        </body> 
    </html> 
    
  2. ist das Protokoll in Funktion

    public static function verifyPass($username,$password,$captchaResponse = 3){ 
        $authenticatedUser = FALSE; 
         $bruteTest = self::_bruteTest($username); 
         if($bruteTest === TRUE && $captchaResponse === 3){ 
    
         $status = "bruteForce"; 
         return $status;  
         } else if($bruteTest === TRUE && $captchaResponse === 0){ 
          //The brute force check was positive and the captcha response failed 
          //Don't even try to log in because the captcha failed. 
          $status = "invalidCaptcha"; 
          return $status; 
         } else if ($bruteTest === TRUE && $captchaResponse === 1){ 
          //The brute force check was positive and the captcha response was successful 
          //Try to log in now. 
          $continueLogin = TRUE; 
         } else if($bruteTest === FALSE){ 
          //The bruteTest was negative, proceed with login. 
          $continueLogin = TRUE; 
         } 
         if($continueLogin === TRUE){ 
         try{ 
          $connection = Database::getDbConnection(); 
          if($connection){ 
           $query = "SELECT usr_name, usr_pass, usr_salt, uid, email_pri FROM users WHERE usr_name=? LIMIT 1"; 
           $stmt = $connection->prepare($query); 
           $stmt->execute(array($username)); 
           $results = $stmt->fetchAll(PDO::FETCH_ASSOC); 
           if($stmt->rowCount() === 0){$authenticatedUser = FALSE;} //Username was not found We are not going to say which was incorrect, only that the "username or password was incorrect" 
           if($results){ 
           $resultsArray = $results[0]; 
           $connection = null; 
           echo "<br />"; 
           $dbUserName = $resultsArray['usr_name']; 
           $dbPass = $resultsArray['usr_pass']; 
           $dbSalt = $resultsArray['usr_salt']; 
           $dbUid = $resultsArray['uid']; 
           $dbEmail = $resultsArray['email_pri']; 
           $passHash = hash('sha512',$password); 
           $passToCheck = hash('sha512',$dbSalt.$passHash); 
           if($passToCheck != $dbPass){ 
            $authenticatedUser = FALSE; //Password did not match. We are not going to say which was incorrect, only that the "username or password was incorrect" 
           } else if ($passToCheck === $dbPass && $username === $dbUserName){ 
            $authenticatedUser = TRUE; 
           } 
          } 
          }else if(!$results){$authenticatedUser = FALSE;} 
         } catch (PDOException $e) { 
          echo "Error: " . $e->getMessage() . "<br />"; 
          die(); 
         } 
    
         try{ 
          if($authenticatedUser === FALSE){ 
           //Log the failed attempt into the database 
           $remoteIp = $_SERVER['REMOTE_ADDR']; 
           try { 
            $connection = Database::getDbConnection(); 
            if($connection){ 
             $query = "INSERT INTO `login_attempts`(`usr_name`, `usr_ip`) VALUES (:usr_name,INET_ATON(:usr_ip))"; 
             $stmt = $connection->prepare($query); 
             $stmt->execute(array(':usr_name' => $username, ':usr_ip' => $remoteIp)); 
            } 
            $connection = null; 
           } catch (PDOException $e){ 
            echo "Error: " . $e->getMessage() . "<br />"; 
            die(); 
            } 
           $status = "invalidPassword"; 
           return $status; 
           exit(); 
          }else if($authenticatedUser === TRUE){ 
           //Clear login attempts from the database 
           self::_clearAttempts($username); 
           //Start the session (if not already started somehow. session and cookie expiration need to be adjusted so that the session does not persist after browser close) 
           if(!isset($_SESSION)){ 
            session_start(); 
           } 
           //Set the session variables 
           $_SESSION['userIp'] = $_SERVER['REMOTE_ADDR']; 
           $_SESSION['userName'] = $dbUserName; 
           $_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT']; 
           $session_name = 'sec_session_id'; 
           $httponly = TRUE; 
           $cookieParams = session_get_cookie_params(); 
           session_set_cookie_params($cookieParams["lifetime"], 
            $cookieParams["path"], 
            $cookieParams["domain"], 
            $httponly); 
           session_name($session_name); 
          } 
    
         } catch (PDOException $e) { 
          echo "Error: " . $e->getMessage() . "<br />"; 
          die(); 
         } 
         //End $continueLogin statement below 
        } 
    } 
    
+2

+1 für diese lange und nicht schlecht gestylt geschriebene Komposition, aber Ihr Code sollte formatiert werden. –

+1

Vielen Dank für die Eingabe, ich entschuldige mich für die fehlende Formatierung. Ich bin immer noch daran gewöhnt, Code auf Stack Overflow zu veröffentlichen. Ich habe meinen Post bearbeitet, um die Formatierung richtig zu formatieren. –

+1

Beachten Sie, dass CAPTCHAs (einschließlich reCAPTCHA) keine solide Abwehr sind. Bots, die ein CAPTCHA erwarten, werden kaum von ihnen verlangsamt. Trotzdem, besser als nichts. Sie könnten auch in Erwägung ziehen, bei jedem weiteren fehlgeschlagenen Login einfach länger und länger zu warten. –

Antwort

1

Verschieben dies:

if(!isset($_SESSION)){ 
    session_start(); 
} 

an die Spitze des Skripts und versuchen Sie es.

oder gerade:

session_start(); 
0

Wie les oben gesagt: session_start am oberen Rand der Seite (oder sogar zu auto-prepend jedem PHP-Skript, mit session_auto_start = 1 in PHP-ini konfiguriert haben) bewirkt, dass Ihre Sitzungsdaten beim Skriptstart geladen werden.

Sie können dann an der gleichen Stelle testen, die Sie für Null-Benutzername und Passwort für einige Variablen wie $ session ['lastPasswordWasInvalid'] testen und wenn es gesetzt ist, überprüfen, ob das Captcha null ist.