1

我已经为此苦苦挣扎了几个小时,只是无法弄清楚我错过了什么。

我正在尝试构建一个无 cookie 登录表单,该表单在会话变量中也没有任何信息,如果攻击者能够修改它们会损害应用程序。

我所有的页面都包含以下代码。

我有两个问题:

  1. 每次我点击另一个页面时,它的行为就像 $_SESSION['token'] 是空的,并像第一次访问一样进入登录页面。

  2. 它返回 $tokenid 和 $tokentype 为空,但是每次加载页面时我都会调用它们(旨在避免将它们放入会话变量中)。

这是我当前的代码:

<?php

define('TIMEOUTMIN', 15);

define('LOCKOUTMIN', 10);

define('LOCKOUTNUM', 3);

include("includes/pp/pbkdf2.php"); // this is basically calling the validate_password function

include ("includes/vars/vars_dbconn.php"); // this contains the db data and $pdo

$userid = $_POST['userid'];
$userpw = $_POST['password'];

$deltoq = "UPDATE LoginUser SET token = ?, online = ? WHERE online < ?";
$prepdeltoq = $pdo->prepare($deltoq);
$prepdeltoq->execute(array(NULL,NULL,time()));

$loginq = "SELECT * FROM LoginUser WHERE ID = ?";
$preplq = $pdo->prepare($loginq);
$preplq->execute(array($userid));
$getuser = $preplq->fetch(PDO::FETCH_ASSOC);
$dbid = $getuser['ID'];
$dbpass = $getuser['hash'];
$dbbp = $getuser['bp'];
$dbltime = $getuser['ltimeout'];

$logintoq = "SELECT * FROM LoginUser WHERE token = ?";
$prepltq = $pdo->prepare($logintoq);        
$prepltq->execute(array($_SESSION['token']));
$getoken = $prepltq->fetch(PDO::FETCH_ASSOC);
$tokenid = $getoken['ID'];
$tokentype = $getoken['type'];
$totoken = $getoken['token'];

$prolonglock = $pdo->prepare("UPDATE LoginUser SET ltimeout = ? WHERE ID = ?");
$addbp = $pdo->prepare("UPDATE LoginUser SET bp = ? WHERE ID = ?");
$loginwhen = $pdo->prepare("UPDATE LoginUser SET lastlogin = ? WHERE ID = ?");
$loginlogq = $pdo->prepare("INSERT INTO LoginUserLog (ID, action)       
    VALUES(:ID, :action)");

$logintokenid = $pdo->prepare("UPDATE LoginUser SET token = ? WHERE ID = ?");
$loginonid = $pdo->prepare("UPDATE LoginUser SET online = ? WHERE ID = ?");
$loginontok = $pdo->prepare("UPDATE LoginUser SET online = ? WHERE token = ?");

if(!function_exists('LoginUser')) {

    function LoginUser($pwmessage) {

        if (session_name() <> 'MyWebApp') session_name('WesoftskyLogin');
        if (!session_id()) session_start();

        $_SESSION['token'] = '';

        include ("includes/header.php"); ?>
        <meta name="description" content="Login - MyWebApp"/>
        <title>Login - MyWebApp</title>
        <script type="text/javascript">
            event.keyCode == '';
                function enterTab() {
                    if (event.keyCode == 13) {
                    var passInput = document.getElementById("password");
                    passInput.focus();
                    }
                }
        </script>
    </head>
    <body onkeyup="enterTab()">
      <div id="homewrap">
        <div id="hometitle">MyWebApp</div>
      </div>
      <div id="id_formwrap">
        <form action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']); ?>" method="post">
            <?php if (empty($pwmessage)) echo '<div>Please enter your login details</div>'; else echo '<div style="color:red">'.$pwmessage.'</div>'; ?><br />
            Login ID<br />
            <input type="text" name="userid" id="id" onKeyPress="return noenter(event)" /><br /><br />            
            <script>document.getElementById("id").focus()</script>
            Password<br />
            <input type="password" name="password" id="password" /><br /><br />
            <input type="submit" name="login" id="Submit" value="Login" />
        </form>
      </div>
    </body>
    </html>

    <?php exit();
    }
}

if(!function_exists('ProlongTime')) {
    function ProlongTime() {
        global $userid; 
        global $logintokenid;
        global $loginonid;
        global $loginontok;
        $timeoutodb = (time () + TIMEOUTMIN*60);
        if (!empty($userid)) {
            $_SESSION['token'] = bin2hex(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM));
            $logintokenid->execute(array($_SESSION['token'], $userid));
            $loginonid->execute(array($timeoutodb, $userid));
        } else {
            $loginontok->execute(array($timeoutodb, $_SESSION['token']));
        }
    }
}

if ($dbltime > time()) {
    $lockcheck = time() + LOCKOUTMIN*60;
    $prolonglock->execute(array($lockcheck,$userid));
    LoginUser('Your account is currently locked');
}

if(isset($_POST['logout'])) {
    $action = "Logged OUT";
    $loginlogq->execute(array(':ID' => $tokenid, ':action' => $action));
    LoginUser('Logged out');
}

if (isset($_POST['login'])) {   
    if ($dbid AND validate_password($userpw, $dbpass)) {  // Good login info
        //session_regenerate_id(true);      
        $action = "Logged IN";
        $loginlogq->execute(array(':ID' => $userid, ':action' => $action));
        $loginwhen->execute(array(time(), $userid));
        $addbp->execute(array(NULL, $userid));
        ProlongTime();
    } else { // Bad login info
        if ($dbbp >= LOCKOUTNUM-1) {
            $lockbp = time() + LOCKOUTMIN*60;
            $prolonglock->execute(array($lockbp,$userid));
            $action = "Locked (wrong password)";
            $loginlogq->execute(array(':ID' => $userid, ':action' => $action));
            LoginUser('Your account has been locked');
        }
        $addbp->execute(array($dbbp+1, $userid));
        $action = "Failed login";
        $loginlogq->execute(array(':ID' => $userid, ':action' => $action));
        LoginUser('Username or password is incorrect');
    }
} elseif (empty($_SESSION['token'])) { // Loading the page first time (new session)
    LoginUser('');
} elseif ($_SESSION['token'] <> $totoken) { // Session timeout
    $action = "Logged OUT (expired)";
    $loginlogq->execute(array(':ID' => $tokenid, ':action' => $action));
    echo 'tokenid: '.$tokenid;
} else ProlongTime(); // While using the app and still within time


$pdo = null;

?>
4

1 回答 1

1

你需要把

session_start()

在页面的开头。

于 2013-04-29T12:04:14.917 回答