Always the same error message - php

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;

Related

CSRF tokem for submit form

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.

Protect form with session token

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'];
...

Registration page not processing data to database

I am developing a website with User registration and login ,after completing the page configuration ,i tried to register it worked perfectly and later next day i tried to register but the page is not loading ,after filling in the data and if i click submit ,it reloads the same register page with no effect ,how to solve this problem
SQL Query Processing code: (class.newuser.php)
enter code here
class User
{
public $user_active = 0;
private $clean_email;
public $status = false;
private $clean_password;
private $clean_username;
private $unclean_username;
public $sql_failure = false;
public $mail_failure = false;
public $email_taken = false;
public $username_taken = false;
public $activation_token = 0;
function __construct($user,$pass,$email)
{
//Used for display only
$this->unclean_username = $user;
//Sanitize
$this->clean_email = sanitize($email);
$this->clean_password = trim($pass);
$this->clean_username = sanitize($user);
if(usernameExists($this->clean_username))
{
$this->username_taken = true;
}
else if(emailExists($this->clean_email))
{
$this->email_taken = true;
}
else
{
//No problems have been found.
$this->status = true;
}
}
public function userPieAddUser()
{
global $db,$emailActivation,$websiteUrl,$db_table_prefix;
//Prevent this function being called if there were construction errors
if($this->status)
{
//Construct a secure hash for the plain text password
$secure_pass = generateHash($this->clean_password);
//Construct a unique activation token
$this->activation_token = generateactivationtoken();
//Do we need to send out an activation email?
if($emailActivation)
{
//User must activate their account first
$this->user_active = 0;
$mail = new userPieMail();
//Build the activation message
$activation_message = lang("ACTIVATION_MESSAGE",array("{$websiteUrl}/",$this->activation_token));
//Define more if you want to build larger structures
$hooks = array(
"searchStrs" => array("#ACTIVATION-MESSAGE","#ACTIVATION-KEY","#USERNAME#"),
"subjectStrs" => array($activation_message,$this->activation_token,$this->unclean_username)
);
/* Build the template - Optional, you can just use the sendMail function
Instead to pass a message. */
if(!$mail->newTemplateMsg("new-registration.txt",$hooks))
{
$this->mail_failure = true;
}
else
{
//Send the mail. Specify users email here and subject.
//SendMail can have a third parementer for message if you do not wish to build a template.
if(!$mail->sendMail($this->clean_email,"New User"))
{
$this->mail_failure = true;
}
}
}
else
{
//Instant account activation
$this->user_active = 1;
}
if(!$this->mail_failure)
{
//Insert the user into the database providing no errors have been found.
$sql = "INSERT INTO `".$db_table_prefix."users` (
`username`,
`username_clean`,
`password`,
`email`,
`activationtoken`,
`last_activation_request`,
`LostpasswordRequest`,
`active`,
`group_id`,
`sign_up_date`,
`last_sign_in`
)
VALUES (
'".$db->sql_escape($this->unclean_username)."',
'".$db->sql_escape($this->clean_username)."',
'".$secure_pass."',
'".$db->sql_escape($this->clean_email)."',
'".$this->activation_token."',
'".time()."',
'0',
'".$this->user_active."',
'1',
'".time()."',
'0'
)";
return $db->sql_query($sql);
}
}
}
}
?>
HTML register.php
enter code here
<?php
require_once("models/config.php");
//Prevent the user visiting the logged in page if he/she is already logged in
if(isUserLoggedIn()) { header("Location: index.php"); die(); }
?>
<?php
//Forms posted
if(!empty($_POST))
{
$errors = array();
$email = trim($_POST["email"]);
$username = trim($_POST["username"]);
$password = trim($_POST["password"]);
$confirm_pass = trim($_POST["passwordc"]);
//Perform some validation
//Feel free to edit / change as required
if(minMaxRange(5,25,$username))
{
$errors[] = lang("ACCOUNT_USER_CHAR_LIMIT",array(5,25));
}
if(minMaxRange(8,50,$password) && minMaxRange(8,50,$confirm_pass))
{
$errors[] = lang("ACCOUNT_PASS_CHAR_LIMIT",array(8,50));
}
else if($password != $confirm_pass)
{
$errors[] = lang("ACCOUNT_PASS_MISMATCH");
}
if(!isValidemail($email))
{
$errors[] = lang("ACCOUNT_INVALID_EMAIL");
}
//End data validation
if(count($errors) == 0)
{
//Construct a user object
$user = new User($username,$password,$email);
//Checking this flag tells us whether there were any errors such as possible data duplication occured
if(!$user->status)
{
if($user->username_taken) $errors[] = lang("ACCOUNT_USERNAME_IN_USE",array($username));
if($user->email_taken) $errors[] = lang("ACCOUNT_EMAIL_IN_USE",array($email));
}
else
{
if(!$user->userPieAddUser())
{
if($user->mail_failure) $errors[] = lang("MAIL_ERROR");
if($user->sql_failure) $errors[] = lang("SQL_ERROR");
}
}
}
if(count($errors) == 0)
{
if($emailActivation)
{
$message = lang("ACCOUNT_REGISTRATION_COMPLETE_TYPE2");
} else {
$message = lang("ACCOUNT_REGISTRATION_COMPLETE_TYPE1");
}
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Registration | <?php echo $websiteName; ?> </title>
<?php require_once("head_inc.php"); ?>
</head>
<body>
<div class="modal-ish">
<div class="modal-header">
<h2>Sign Up</h2>
</div>
<div class="modal-body">
<div id="success">
<p><?php echo $message ?></p>
</div>
<div id="regbox">
<form name="newUser" action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<p>
<label>Username:</label>
<input type="text" name="username" />
</p>
<p>
<label>Password:</label>
<input type="password" name="password" />
</p>
<p>
<label>Re-type Password:</label>
<input type="password" name="passwordc" />
</p>
<p>
<label>Email:</label>
<input type="text" name="email" />
</p>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" name="new" id="newfeedform" value="Register" />
</div>
</form>
</div>
<div class="clear"></div>
<p style="margin-top:30px; text-align:center;">Login / Forgot Password? / Home Page</p>
</body>
</html>
Its all due to div tags:
2 divisions closed within the form tag but they are opened outside the form tag.
So try by enclosing the whole form within one div(regbox) Including submit.
And make sure that no div is closed within form tag which is opened outside form tag.

PDO Simple User Class Wont Work

i'm trying to create a simple user class but i can't get the data in the database i tried a lot of different code now here is the user class
namespace MonetizeMedia;
class User {
private $uid;
private $fields;
public function __construct() {
$this->uid = null;
$this->fields = array('username' => '',
'password' => '');
}
public function __get($field) {
if($field == 'uid')
{
return $this->uid;
}
else
{
return $this->fields[$field];
}
}
public function __set($field, $value) {
if(array_key_exists($field, $this->fields))
{
$this->fields[$field] = $value;
}
}
public function createUser() {
try {
$db = new \MonetizeMedia\Database;
$bcrypt = new \MonetizeMedia\Bcrypt(15);
$sql = "INSERT INTO users(username, password) VALUES(:username, :password)";
$stmt = $db->prepare($sql);
$stmt->bindParam(":username", $username);
$stmt->bindParam(":password", $bcrypt->hash($password));
$stmt->execute();
return "Registration Successful";
} catch ( PDOException $e ) {
return $e->getMessage();
}
}
and here is the register page
<?php
ob_start();
session_start();
include 'classes/user.class.php';
if(isset($_POST['submitted'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$User->username = $username;
$User->password = $password;
if($User->createUser()) {
echo "DONE!";
}
else
{
echo "An error occured while creating your account. Please try later.";
return;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Register</title>
</head>
<body>
<form method="post" action="">
<ul>
<li>
<label for="usn">Username : </label>
<input type="text" name="username" />
</li>
<li>
<label for="passwd">Password : </label>
<input type="password" name="password" />
</li>
<li class="buttons">
<input type="submit" name="register" value="Register" />
</li>
</ul>
</form>
</body>
</html>
i'm trying to learn php and pdo so i'm not so good at the moment

Why aren't my form session messages being shown? (Jquery?)

I have a page here: https://github.com/alexwaters/PWTKD-new-CMS/blob/master/taekwondo/schedule-dev.php that is not showing my session messages: <?php echo output_message($message); ?>
I have been trying to track down what the heck is wrong with them, but have no idea. They work on other pages but not this one.
Can someone please help me find the noobie mistakes I made?
Per request here is some of the code that may be relevant:
schedule-dev.php
<?php require_once("../includes/initialize.php"); ?>
<?php $schedules = Schedule::find_all();?>
<?php $messages = Messages::find_by_id(1);?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link href="css/style.css" rel="stylesheet" type="text/css" />
<script src="jquery-1.2.6.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#contactLink").click(function(){
if ($("#contactForm").is(":hidden")){
$("#contactForm").slideDown("slow");
}else{
$("#contactForm").slideUp("slow");
}
});
});
function closeForm(){
$("#messageSent").show("slow");
setTimeout('$("#messageSent").hide();$("#contactForm").slideUp("slow")', 2000);
}
</script>
...
<?php
if(isset($_POST['signupSubmit'])){
$signup = new Signup();
$signup->name = $_POST['name'];
$signup->age = $_POST['email'];
if($signup->save()) {
$session->message("We will contact you with details.");
redirect_to('schedule.php');
} else {
$message = join("test", $signup->errors);
}
}
?>
<?php echo output_message($message); ?>
<div id="contactFormContainer">
<div id="contactLink"></div>
<div id="contactForm">
<fieldset>
<label for="name">Name *</label>
<input id="name" type="text" />
<label for="email">Email address *</label>
<input id="email" type="text" />
<input id="sendMail" type="submit" name="signupSubmit" onclick="closeForm()" />
<span id="messageSent"></span>
</fieldset>
</div>
</div>
Signup.php
<?php
// If it's going to need the database, then it's
// probably smart to require it before we start.
require_once(LIB_PATH.DS.'database.php');
class Signup extends DatabaseObject {
protected static $table_name="signup";
protected static $db_fields=array('id', 'name','email');
public $id;
public $name;
public $email;
public $errors=array();
public function save() {
// A new record won't have an id yet.
if(isset($this->id)) {
// Really just to update the name
$this->update();
return true;
} else {
// Make sure there are no errors
// Can't save if there are pre-existing errors
if(!empty($this->errors)) { return false; }
// Make sure the name is not too long for the DB
if(strlen($this->name) >= 255) {
$this->errors[] = "Name must be <= 255 characters long.";
return false;
}
if(strlen($this->email) >= 255) {
$this->errors[] = "Email must be <= 255 characters long.";
return false;
}
if(empty($email)) {
$this->errors[] = "Please enter an email address";
return false;
}
//Finally add the item to the DB
if($this->create()) {
return true;
} else {
//
$this->errors[] = "Send failed, please contact us";
return false;
}
}
}
and some other generic class stuff
message method from session.php
public function message($msg="") {
if(!empty($msg)) {
// then this is "set message"
// make sure you understand why $this->message=$msg wouldn't work
$_SESSION['message'] = $msg;
} else {
// then this is "get message"
return $this->message;
}
}
Don't you need to add session_start() to you php file? Try doing that, let me know if that helps.
I had to use $this-email in the save method
I needed to make the form an actual post form
The session message wasn't being outputted(?) because it wasn't grabbing the post vars

Categories