I'm generating a form submission security token in software.
The idea is to generate a token as soon as the user arrives on the page hosting the form
Allow the user to fill in the form
And only if the token initialized as soon as the user landed on the page is the same as the one in an input field, then run the code, otherwise no
This is to avoid CSRF
Methodology
1: Create a function that generates a token | create a file: config.php
function RandomToken($length = 32){
if(!isset($length) || intval($length) <= 8 ){
$length = 32;
}
if (function_exists('random_bytes')) {
return bin2hex(random_bytes($length));
}
if (function_exists('mcrypt_create_iv')) {
return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
}
if (function_exists('openssl_random_pseudo_bytes')) {
return bin2hex(openssl_random_pseudo_bytes($length));
}
}
function Salt(){
return substr(strtr(base64_encode(hex2bin(RandomToken(32))), '+', '.'), 0, 44);
}
$token = (RandomToken())."\n".Salt()."\n";
2: include config.php, in the file hosting the form
3: write the rules
if (isset($_POST['submit']))
{
session_start();
$_SESSION['t'] = $token;
if ( ($_SESSION['t'] === $_POST['csrf_token_p']))
{
/* write code if this is correct */
}else{
/* write code if this it's not correct */
}
}
4: write the form
<form action="page.php" method="post">
<input type="text" name="csrf_token_p" value="<?php echo $token ?>">
<input name="submit" value="modifica" type="submit">
</form>
error: I always get that the two tokens do not match. why?
edit part
config.php
<?php ob_start(); session_start();
/*
* https://www.php.net/manual/en/function.random-bytes.php
* funzione per la creazione di un codice unico contro i CSRF attack
* */
function RandomToken($length = 32){
if(!isset($length) || intval($length) <= 8 ){
$length = 32;
}
if (function_exists('random_bytes')) {
return bin2hex(random_bytes($length));
}
if (function_exists('mcrypt_create_iv')) {
return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
}
if (function_exists('openssl_random_pseudo_bytes')) {
return bin2hex(openssl_random_pseudo_bytes($length));
}
}
function Salt(){
return substr(strtr(base64_encode(hex2bin(RandomToken(32))), '+', '.'), 0, 44);
}
$token = (RandomToken())."\n".Salt()."\n";
session_start();
$_SESSION['t'] = randomToken();
/*------------------------------------------------------------------------------------------------------------*/
form-page.php
<?php ob_start(); session_start();
include '../connection/cnt.php';
?>
if (isset($_POST['submit'])){
session_start();
if (!empty($_POST))
{
if (!array_key_exists('csrf_token_p', $_POST))
{
$_POST['t'] = null;
?>
<script type="text/javascript">
window.location = "p_tl.php?edit=Y";
</script>
<?php
}
if ($_SESSION['t'] !== $_POST['csrf_token_p'])
{
// BAD TOKEN! BAD!
?>
<script type="text/javascript">
window.location = "p_tl.php?edit=N";
</script>
<?php
}
}
}
?>
<form id="validate" action="p_tl.php" method="post" class="needs-validation" novalidate>
<input style="display: " type="text" name="csrf_token_p" value="<?php echo $token ?>" class="form-control" id="validationCustom01"
required>
<input
style="background-color: #9da1a4;color: #fff;"
name="submit"
value="modifica"
class="btn btn-sm"
type="submit">
</form>
This is wrong:
if (isset($_POST['submit'])) {
session_start();
$_SESSION['t'] = $token;
You need to start the session in config, and create and save the token there. Because that is the flow that will create the form. Otherwise, a different session will be opened upon submit.
So:
config.php
session_start();
$token = randomToken();
$_SESSION['t'] = $token;
print "<form...";
// In produzione, cambia questo in "hidden", non "text"
print "<input type=\"text\" name="csrf_token_p" value=\"{$token}\" />";
// The rest of the form with submit button
print "</form>";
form_receive.php
session_start();
if (!empty($_POST)) {
if (!array_key_exists('csrf_token_p', $_POST)) {
$_POST['t'] = null;
}
if ($_SESSION['t'] !== $_POST['csrf_token_p']) {
// BAD TOKEN! BAD!
die("Token mismatch");
}
// Okay.
Related
I'm new to PHP and I'm trying to create an easy form that has multiple steps. For each step, a validation of the input is happening before the user is directed to the next page. If the validation fails, the user should stay on the same page and an error message should be displayed. In the end, all entries that the user has made should be displayed in an overview page.
What I have been doing to solve this, is to use a boolean for each page and only once this is true, the user can go to the next page. This is not working as expected unfortunately and I guess it has something to do with sessions in PHP... I also guess that there's a nicer way to do this. I would appreciate some help!
Here's my code:
<!DOCTYPE HTML>
<html>
<head>
<title>PHP Test</title>
<style>
.error {color: #FF0000;}
</style>
</head>
<body>
<?php
session_start();
$_SESSION['$entryOne'] = "";
$_SESSION['$entryOneErr'] = $_SESSION['$emptyFieldErr'] = "";
$_SESSION['entryOneIsValid'] = false;
$_SESSION['$entryTwo'] = "";
$_SESSION['$entryTwoErr'] = "";
$_SESSION['entryTwoIsValid'] = false;
// Validation for first page
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['submitEntryOne'])) {
if (!empty($_POST["entryOne"])) {
// Check for special characters
$_SESSION['$entryOne'] = removeWhitespaces($_POST["entryOne"]);
$_SESSION['$entryOneErr'] = testForIllegalCharError($_SESSION['$entryOne'], $_SESSION['$entryOneErr']);
// If error text is empty set first page to valid
if(empty($_SESSION['$entryOneErr'])){
$_SESSION['$entryOneIsValid'] = true;
}
} else {
// Show error if field hasn't been filled
$_SESSION['$emptyFieldErr'] = "Please enter something!";
}
// Validation for second page
} else if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['submitEntryTwo'])) {
if (!empty($_POST["entryTwo"])) {
// Check for special characters
$_SESSION['$entryTwo'] = removeWhitespaces($_POST["entryTwo"]);
$_SESSION['$entryTwoErr'] = testForIllegalCharError($_SESSION['$entryTwo'], $_SESSION['$entryTwoErr']);
// If error text is empty set second page to valid
if(empty($_SESSION['$entryTwoErr'])){
$_SESSION['$entryTwoIsValid'] = true;
}
} else {
// Show error if field hasn't been filled
$_SESSION['$emptyFieldErr'] = "Please enter something!";
}
}
//Remove whitespaces at beginning and end of an entry
function removeWhitespaces($data) {
$data = trim($data);
return $data;
}
//Check that no special characters were entered. If so, set error
function testForIllegalCharError($wish, $error){
$illegalChar = '/[\'\/~`\!##\$%\^&\*\(\)_\-\+=\{\}\[\]\|;:"\<\>,\.\?\\\]/';
if (preg_match($illegalChar,$wish)) {
$error = "Special characters are not allowed";
} else {
$error = "";
}
return $error;
}
?>
<?php if (isset($_POST['submitEntryOne']) && $_SESSION['$entryOneIsValid'] && !$_SESSION['$entryTwoIsValid']): ?>
<h2>Second page</h2>
<p>Entry from first Page: <?php echo $_SESSION['$entryOne'];?></p>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Entry Two: <input type="text" name="entryTwo" value="<?php echo $_SESSION['$entryTwo'];?>">
<span class="error"><?php echo $_SESSION['$entryTwoErr'];?></span>
<br><br>
<input type="submit" name="submitEntryTwo" value="Next">
</form>
<?php elseif (isset($_POST['submitEntryTwo']) && $_SESSION['$entryTwoIsValid']): ?>
<h2>Overview</h2>
<p>First entry: <?php echo $_SESSION['$entryOne'];?></p>
<p>Second Entry: <?php echo $_SESSION['$entryTwo'];?></p>
<?php else: ?>
<h2>First page</h2>
<span class="error"><?php echo $_SESSION['$emptyFieldErr'];?></span>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<br><br>
First entry: <input type="text" name="entryOne" value="<?php echo $_SESSION['$entryOne'];?>">
<span class="error"> <?php echo $_SESSION['$entryOneErr'];?></span>
<br><br>
<input type="submit" name="submitEntryOne" value="Next">
</form>
<?php endif; ?>
</body>
</html>
You are setting your session variables to "" at the top of your script.
Check if your variable is set before setting to blank.
Check if Session Variable is Set First
<?php
//If variable is set, use it. Otherwise, set to null.
// This will carry the variable session to session.
$entryOne = isset($_REQUEST['entryOne']) ? $_REQUEST['entryOne'] : null;
if($entryOne) {
doSomething();
}
?>
Tips
Then you can use <?= notation to also echo the variable.
Do this $_SESSION['variable'] instead of $_SESSION['$variable'] (you'll spare yourself some variable mistakes).
<h2>Second page</h2>
<p>Entry from first Page: <?= $entryOne ?></p>
Example Script
This could be dramatically improved, but for a quick pass:
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
//Check that no special characters were entered. If so, set error
function hasIllegalChar($input){
$illegalChar = '/[\'\/~`\!##\$%\^&\*\(\)_\-\+=\{\}\[\]\|;:"\<\>,\.\?\\\]/';
if (preg_match($illegalChar, $input)) {
return true;
}
return false;
}
session_start();
// Destroy session and redirect if reset form link is pressed.
if(isset($_GET['resetForm']) && $_GET['resetForm'] == "yes")
{
echo "SESSION DESTROY";
session_destroy();
header("Location: ?");
}
// Session
$page = isset($_SESSION['page']) ? $_SESSION['page'] : 1;
$errors = [];
// Value history.
$valueOne = isset($_SESSION['valueOne']) ? $_SESSION['valueOne'] : null;
$valueTwo = isset($_SESSION['valueTwo']) ? $_SESSION['valueTwo'] : null;
// Clean inputs here
$fieldOne = isset($_REQUEST['fieldOne']) ? trim($_REQUEST['fieldOne']) : null;
$fieldTwo = isset($_REQUEST['fieldTwo']) ? trim($_REQUEST['fieldTwo']) : null;
// First form
if ($page == 1) {
// If field two is submitted:
if ($fieldOne) {
//Validate inputs
if(hasIllegalChar($fieldOne)) {
$errors[] = "You entered an invalid character.";
}
if (count($errors) == 0 ){
$valueOne = $_SESSION['valueOne'] = $fieldOne;
$page = $_SESSION['page'] = 2;
}
}
}
// Second form
else if ($page == 2) {
// If field two is submitted:
if ($fieldTwo) {
//Validate inputs
if(hasIllegalChar($fieldTwo)) {
$errors[] = "You entered an invalid character.";
}
if (count($errors) == 0 ){
$valueTwo = $_SESSION['valueTwo'] = $fieldTwo;
$page = $_SESSION['page'] = 3;
}
}
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title>PHP Test</title>
<style>
.error {
color: #FF0000;
}
</style>
</head>
<body>
<?php
// troubleshoot
if (true) {
echo "<pre>";
var_dump($_REQUEST);
var_dump($_SESSION);
echo "</pre>";
}
echo "<h1>Page " . $page . '</h1>';
if (count($errors) > 0) {
$errorMsg = implode('<br/>',$errors);
echo '<div class="error">Some errors occurred:<br/>' . $errorMsg . '</div>';
}
?>
<?php if ($page == 3): ?>
<h2>Overview</h2>
<p>First entry: <?= $valueOne;?></p>
<p>Second Entry: <?= $valueTwo;?></p>
Reset
<?php elseif ($page == 2): ?>
<p>Entry from first Page: <?= $valueOne; ?></p>
<form method="post" action="<?= $_SERVER["PHP_SELF"] ?>">
Entry Two: <input type="text" name="fieldTwo" value="<?= $fieldTwo ?>" autofocus>
<br><br>
<input type="submit">
</form>
<?php else: ?>
<form method="post" action="<?= $_SERVER["PHP_SELF"] ?>">
<br><br>
Entry One: <input type="text" name="fieldOne" value="<?= $fieldOne; ?>" autofocus>
<br><br>
<input type="submit">
</form>
<?php endif; ?>
</body>
<html>
You can run the following command to test out the page without using a fancy tool like WAMP or LAMP.
php -S localhost:8000 index.php
You can now access in the browser at http://localhost:8000.
I wrote a script to protect my form with session token; however my script does not work if I try to validate form fields before checking for the token. Would someone help me figure out what is wrong with my script please?
<?php
session_start();
class TOKEN {
public static function generate() {
return $_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(15));
}
public static function check($token) {
if (isset($_SESSION['token']) && $token === $_SESSION['token']) {
unset($_SESSION['token']);
return true;
}
return false;
}
}
?>
<?php
$display_form = FALSE;
if (isset($_POST['submit'])) {
$username = $_POST['username'];
$userpass = $_POST['userpass'];
if (strlen($username) < 4) {
$error_name = 'required';
$display_form = true;
$validation_error = true;
}
if (strlen($userpass) < 8) {
$error_pass = 'required';
$display_form = true;
$validation_error = true;
}
if (!$validation_error) {
if (TOKEN::check($_POST['token'])) {
echo 'process form';
} else {
echo 'invalid security token';
}
}
} else {
$display_form = TRUE;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<?php
if ($display_form == true) {
?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI']); ?>">
<input type="hidden" name="token" value="<?php echo TOKEN::generate(); ?>">
<input type="text" name="username" id="" placeholder="username">
<?php echo $error_name; ?>
<br>
<input type="password" name="userpass" id="" placeholder="Password">
<?php echo $error_pass; ?>
<br>
<input type="submit" name="submit" value="Sign in">
</form>
</body>
</html>
<?php
}
?>
I suppose that the problem here is in the following.
You have token in the form and token in the session. They're equal.
When you fill the form with errors - your form loads again. But! In the session you have previous token, from point 1, and in the form you have new token.
You submit again and check different tokens.
So, the solution is to unset token always, no matter you have wrong or right values in the form.
Update:
I suppose it should be something like:
if (!$validation_error) {
// here token will be removed in `TOKEN::check`
if (TOKEN::check($_POST['token'])) {
echo 'process form';
} else {
echo 'invalid security token';
}
} else {
// remove token implicitly
TOKEN::remove();
}
And in TOKEN:
public static function check($token) {
$result = false;
if (isset($_SESSION['token'])) {
if ($token === $_SESSION['token']) {
$result = true;
}
// if token set - remove it
self::remove();
}
return $result;
}
public static function remove() {
unset($_SESSION['token']);
}
This code is very hard to read. I can't tell when if statements start and end. Also stop using classes for everything. Use procedural programming like a big boy.
Your issue is a simple one. $validation_error was not initialized in the outer scope. Meaning that it was not saved between if statments.
To fix this simply add $validation_error = false at the outer scope:
...
$display_form = FALSE;
$validation_error = false; // right here
if (isset($_POST['submit'])) {
$username = $_POST['username'];
$userpass = $_POST['userpass'];
...
My PHP code for login works fine in my local server. It's also working on live server but always fails at first attempt without giving any error (validation or user verification errors).
Can't put whole code as it's on a live server. Found many questions on web with same problem (even on stackOverflow) but without any answwer.
Please help!
Login Page:
<form class="form-signin" id="form-signin" action="./" name="LoginForm" role="form">
<h2 class="form-signin-heading">Please Sign In</h2>
<div class="input-group">
<span class="input-group-addon"></span>
<input type="text" class="form-control" id="username" name="username" placeholder="Username" autofocus>
</div>
<div class="input-group">
<span class="input-group-addon"></span>
<input type="password" class="form-control" id="password" name="password" placeholder="Password" >
</div>
<button type="submit" class="btn btn-lg btn-primary btn-block" id="signinBtn" data-loading-text="Verifying...">Sign in</button>
</form>
javascript:
$(document).ready(function(){
$("#form-signin").submit(function(){ // actions when form is submitted
$("#msg").hide(); //hide the danger alert
var btn = $("#signinBtn");
btn.button('loading'); // change sign-in button state to loading till ajax complete
username = $("#username").val();
password = $("#password").val();
if ((username==null || username=="") || (password==null || password=="") ) // i.e if any of the username password field is empty
{
$("#msg").html("Please Fill the form completely");
btn.button('reset');
$("#form-signin").effect('shake'); // shake effect --> needs jquery.ui
$("#msg").show(200);
return false;
}
else{
$.ajax({
type: "POST",
url: "verify.php",
data: "username="+username+"&password="+password,
success: function(verified){
// if user is verified redirect according to the level of user
if(verified == 'true1')
window.location = "http://example.com/page1.php";
else if(verified == 'true2')
window.location = "http://example.com/page2.php";
else if(verified == 'true3')
window.location = "http://example.com/page3.php";
else if(verified == 'false')
{
//else display error
$("#msg").html("<strong>Invalid</strong> username password combo!");
$("#form-signin").effect('shake');
$("#msg").show(200);
btn.button('reset');
}
}
});
return false;
}
}); // .submit function ends
}); //.ready function ends
PHP code:
<?php
include("DataBaseLogin.php");
session_start();
$user = $_POST["username"];
$pass = $_POST["password"];
$user = htmlspecialchars($user);
$pass = htmlspecialchars($pass);
$user = mysql_real_escape_string($user, $db_handle);
$pass = mysql_real_escape_string($pass, $db_handle);
if ($db_found)
{
$result = mysql_query("SELECT * FROM user_table WHERE uname = '$user' AND pword = '$pass'");
$resultArray=mysql_fetch_assoc($result);
if($resultArray['uname']==$user && $resultArray['pword']==$pass)
{
//If user verified
$_SESSION['login'] = "1";
$_SESSION["current_user"]=$user;
$_SESSION['Level'] = $resultArray['Level'];
$Level = $_SESSION['Level'];
if($Level==1)
echo 'true1';
else
if($Level==2)
echo 'true2';
else if($Level==3)
echo 'true3';
}
else
{
$_SESSION['login'] = "";
echo 'false';
mysql_close($db_handle);
}
}
else
{
echo "db not found";
mysql_close($db_handle);
}
?>
code for page1 //after verification
<?PHP
session_start();
include("DataBaseLogin.php");
if (!(isset($_SESSION['login']) && $_SESSION['login'] != ''))
{
header ("Location: index.php");
}
else if($_SESSION['Level'] !=1)
die("You are not allowed on this page");
?>
now html code for page1 to show if user is allowed.
<?PHP
session_start();
include("DataBaseLogin.php");
if (isset($_SESSION['login']) && !empty($_SESSION['login']))
{
header ("Location: page1.php");
}
else if($_SESSION['Level'] !=1 || empty($_SESSION['login'])) {
header ("Location: index.php");
}
?>
try putting this at the end of your script:
session_write_close();
if you are using classes (for example, when using a framework controller), put it in the destruct function
function __destruct(){
session_write_close();
}
i want to know how to send value form my_name in index.php below to result.php.
below is the php code to check for errors after the input form.
and how to send form results that there is no error to result.php
here is index.php
<?php
if ($_POST["_submit_check"]) {
if ($form_errors = validate_form()) {
show_form($form_errors);
} else {
process_form();
}
} else {
show_form();
}
function process_form() {
//if doesnt makes error
//i want to send result "my_name" to result.php
header('Location: result.php');
}
function show_form($errors = '') {
if ($errors) {
print implode('</li><li><br>', $errors);
print '</li></ul>';
}
print<<<_HTML_
<form method="POST" action="$_SERVER[PHP_SELF]">
Your name: <input type="text" name="my_name">$errors[0];
<br/>
<input type="submit" value="Submit">
<input type="hidden" name="_submit_check" value="1">
</form>
_HTML_;
}
function validate_form() {
$errors = array();
if (strlen($_POST['my_name']) < 3) {
$errors[] = "Your name must be at least 3 letters long.";
}
return $errors;
}
?>
here is result.php
<?php
//prints result form from index.php
?>
you can do it with HTTP GET variables
header('Location: result.php?name='.$_POST['my_name']);
in result.php
you can see the value
echo $_GET['name'];
PHP session variables hold information among pages.
Please try this.
At index.php
<?php
session_start();
// set post date into session variable
$_SESSION['my_name'] = $_POST['my_name'];
$_SESSION['my_number'] = $_POST['my_number'];
?>
And at result.php
<?php
session_start();
// get date from session variable
$my_name = $_SESSION['my_name'];
$my_number= $_SESSION['my_number'];
echo $my_name;
echo $my_number;
?>
Its a log in form, and a class_login.php file. I got a token, to verify the form submissions. Its a random string and i send it hidden. I got 3 error messages on my class. Invalid form submission. Invalid form data. and Invalid Username/Password. The problem is doesnt matter what i do i get stuck on the first error invalid form submission. Its like the token i send never matches the session token. But when i remove that part i always get the invalid form data, even if i write a correct existing user/password. Need some help here please:
<?php
class class_login
{
private $id;
private $username;
private $password;
private $passmd5;
private $errors;
private $access;
private $login;
private $ltoken;
public function __construct()
{
$this->errors = array();
$this->login = isset($_POST['login'])? 1:0;
$this->access = 0;
$this->ltoken = $_POST['ltoken'];
$this->id = 0;
$this->username = ($this->login)? $this->filter($_POST['username']) : $_SESSION['username'];
$this->password = ($this->login)? $this->filter($_POST['password']) : '';
$this->passmd5 = ($this->login)? md5($this->password) : $_SESSION['password'];
}
public function isLoggedIn()
{
($this->login)? $this->verifyPost() : $this->verifySession();
return $this->access;
}
public function filter($var)
{
return preg_replace('/[^a-zA-Z0-9]/','',$var);
}
public function verifyPost()
{
try
{
if(!$this->tokenValid())
throw new Exception('Invalid Form Submission!');
if(!$this->isDataValid())
throw new Exception('Invalid Form Data!');
if(!$this->verifyDatabase())
throw new Exception('Invalid Username/Password!');
$this->access = 1;
$this->registerSession();
}
catch(Exception $e)
{
$this->errors[] = $e->getMessage();
}
}
public function verifySession()
{
if($this->sessionExist() && $this->verifyDatabase())
$this->access = 1;
}
public function verifyDatabase()
{
include('db_connect.php');
$data = mysql_query("SELECT ID FROM users WHERE username = '($this->username)' AND password = '($this->passmd5)'");
if (mysql_num_rows($data))
{
list($this->id) = #array_values(mysql_fetch_assoc($data));
return true;
}
else
return false;
}
public function isDataValid()
{
return (preg_match('/[^a-zA-Z0-9]$/', $this->username) && preg_match('/[^a-zA-Z0-9]$/', $this->password))? 1:0;
}
public function tokenValid()
{
return (!isset($_SESSION['ltoken']) || $this->ltoken != $_SESSION['ltoken'])? 0 : 1;
}
public function registerSession()
{
$_SESSION['ID'] = $this->id;
$_SESSION['username'] = $this->username;
$_SESSION['password'] = $this->passmd5;
}
public function sessionExist()
{
return (isset($_SESSION['username']) && isset($_SESSION['password']))? 1 : 0;
}
public function show_errors()
{
foreach($this->errors as $value)
echo $value."</br>";
}
}
?>
Here is the login_form.php
<?php
$check = 0;
$ltoken = $_SESSION['ltoken'] = md5(uniqid(mt_rand(), true));
if(isset($_POST['login']))
{
$check = 1;
include('class_login.php');
$login = new class_login();
if ($login->isLoggedIn())
echo "Success!";
else
$login->show_errors();
}
?>
<link rel="stylesheet" href="CSS/regstyle.css" type="text/css" />
<script src="JS/jquery-1.7.2.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var checker = <?php echo $check; ?>;
if(checker == 1)
{
$("#logform").slideDown("fast")
}
});
</script>
<div id="content">
<?php echo $ltoken; ?>
<!-- Begin Form -->
<div class="form-content">
<form class="reg-form" method="post" action="<?php $_SERVER['PHP_SELF'] ?>">
<fieldset>
<div class="divusername">
<label for="username">Username:</label>
<input type="text" id="username" name="username" placeholder="Your Username Here" />
</div>
<div class="password">
<label for="password">Password:</label>
<input type="password" id="password" name="password" placeholder="Your Password Here" />
</div>
<div class="submit-button">
<input type="hidden" name="ltoken" value="<?php echo $ltoken; ?>" />
<input type="submit" name="login" value="Login" />
</div>
</fieldset>
</form>
</div>
</div>
I suspect that you forgot to start the session using session_start(). Please show us how you use this class. (The file where you use it.)
Edit
Disregard the above. The problem here is that you are setting the $_SESSION['ltoken'] to a new random value on each page load. That's why the posted value (this is one generation 'behind') never matches.
Separate out this code:
return (!isset($_SESSION['ltoken']) || $this->ltoken != $_SESSION['ltoken'])? 0 : 1;
It may or may not be accurate, but it's not readable and makes your debugging harder. I think it may be throwing you off because you're using the if or else as the second condition.
if( ! isset( $_SESSION['ltoken'] ) return false;
return ( $this->ltoken != $_SESSION['ltoken']) ? 0 : 1;