i am using jquery chat tutorial
for chatting. I am working on this to make registration separately using a username and password.
Right now it is taking username and gravatar for registration. I changed my code for registration. But if it gets a username in the database, it just updates its timestamp and password leaving the username unchanged. But i want to show error if the username already exists. How can i achieve this goal?
Also it is deleting the user from database after some time of idle state. How can i remove this functionality?
Set the name field in webchat_users to unique. Or insert following lines of code into your PHP class:
$userEnteredName = 'John';
$row = mysql_fetch_assoc(DB::query("SELECT `name` FROM `webchat_users` WHERE `name` LIKE '".mysql_real_escape_string($userEnteredName)."' LIMIT 1"));
if(!empty($row['name'])) {
// Username taken
die('Username taken.');
} else {
// Proceed registration.
}
For your second problem: Simply remove line 33 & 34 from Chat.class.php.
Related
I've a website and its access should be restricted. So, on entering the page, before page load we should restrict the access with three fields i.e., username and password of client and specific password for that page, these three were created by me and are stored in a database.
I've basic knowledge of Javascript and PHP.
My idea is before the page load, Javascript should get the three field values entered by user and by PHP we have to validate using a database, if the match occurs then page should load if not the access to that page should be denied.
in brief on hitting URL and before page load connection to the database has to be made and user/client entered 3 fields should be taken and be verified with MYSQL database by PHP and on successful authentication page should be displayed.
Please come up with code suggestions. Thanks in advance :)
i have created a function which you may use:
<?php
function login($username,$password,$salt,$db,$table,$usercolumn,$passwordcolumn,$con)
{
$user=mysql_real_escape_string($username);
$password=mysql_real_escape_string($password);
$db=mysql_select_db($db,$con);
if(!$db)
{
return "connection error";
}
else
{
$sql="SELECT * FROM `$table` WHERE `$usercolumn`='$user';";
$enc=$password;
foreach($salt as $value)
{
if($value=="md5")
{
$enc=md5($enc);
}else
{
$enc=crypt($enc,$value);
}
}
$resource=mysql_query($sql);
$row=mysql_fetch_array($resource);
$passdb=$row[$passwordcolumn];
if($passdb==$enc)
{
$sucess=true;
}else
{
$sucess=false;
}
}
return $sucess;
}
?>
you may use this and if it returns true, that means username and passwords are correct now you have to validate your third option...
to use this function, you just need to call like this after copying that function to a file, if it is named to "logger.php",
<?php
require("logger.php");
$enc=array("salt","md5","differentsalt")//your encryption such as if you have encrypted using 'salt' at first then using md5 hash and again 'differentsalt',then you need to give like i have given
if(login($username,$password,$enc,$db,$table_name,$usercolumn,$passwordcolumn,$con))//$username is the username which user supplied,$password is password user supplied,$enc is the encryption and it must be an array... which is also given above,$db is database name,$table_name is the table where username and encrypted password are stored,$usercolumn is the column name where username are stored, $passwordcolumn is the column where encrypted password are stored, and last $con is the connection identifier, you may have given, $con=mysqli_connect("username","password");
//if all the parameters are supplied correctly, it will check for the username and password matching and you will have to check the third option
{
//now validate your third option here...
//if you are here, that means password and username has matched
}
else
{
//this means username and password didnt matched... so output the error
}
?>
for accepting username and password, you may create a form and ask password there and then submit...
I am using the EZ Publish CMS:
What is currently happening:
From the forgot password page, user enters the email address that they
used to register and submits
User receives an email with a password generating link which
uses a hash to confirm their identity.
User receives an email with a freshly generated password
User returns to site using the link from their email which takes them
to a form that asks for the old password (which was just generated
and has been sent to their email) and for them to enter a new
password.
What I want to happen:
From the "forgot password" page, user enters the email address that they
used to register and submits
User receives an email with a link to the "enter new password" form
On the "enter new password" form, user is not required to enter old
password because identity has already been confirmed by hash and
therefore only has to enter the new password.
I am using the EZMBPAEX extension which has the original 4 step process.
There doesn't seem to be any documentation or discussion about removing the "email the user a new password" step but my client has a very strict no passwords sent by email policy so I can't flex on this.
Does anyone know where I can find documentation on how to edit this functionality?
I think the file that will need to be edited is located in:
/extension/ezmbpaex/modules/userpaex/forgotpassword.php
First of All create a function to generate a random string for you, let's say you need to create a random string of 32 caracters, choose any number of caracters you want
Function to generate random code which will be sent by email and added to db
function genRandomString() {
$length = 32;
$characters = "0123456789abcdefghijklmnopqrstuvwxyz";
$string ="";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, (strlen($characters))-1)];
}
return $string;
}
Next, create a new table using php myAdmin, a table names forgotten_passes which contain three columns, let's say you already did that
$key = genRandomString(); // assign random code
$assign = $db->query("INSERT INTO `YOUR_DB_NAME`.`forgotten_pass` (`email` ,`randomKey` , `time`)
VALUES ('$email', '$key', CURRENT_TIMESTAMP );");
Next send an email which contain a link to your resetpassword.php page ( the page where user asked to choose a new password and confirm it, but do not forget to assign the generated key to a get variable , that's easy, just when you the link
www.yourdomain.com/pass_reset.php ( ADD ?secretkey=THE_GENERATED_HERE )
so the link sent to the email adresse of the person who need to reset the password should contain something like :
Hello username, to reset your password click on the link below or copy/past it into your browser
The link : http://www.yourdomain.com/pass_reset.php?secretKey=a12s236d5c8d4fkejus10a1s2d4c8741
When user click on the link, he will go to a page which verify his email and its corresponding random key in sql database, if it found that there are really an email and that random kay, then the user is really confirmed it's email, so this page should contain something like below :
<?php
if (isset($_GET['secretKey'])) {
$secretKey = $_GET['secretKey'];
// Check wether it really exist in database
$sql = 'select * from forgotten_pass WHERE email=$The_User_Email and randomKey='$secretKey'';
}
Now, just count the number of rows to see if there are returned data, if there are returned data than the user really connected to its inbox and clicked the link.
Just do the following :
if mysql_num_rows($sql)>0 { echo "Success, ";
?>
// in this part type the html code which displays two inputs text, password
// and confirm password that connect to database and update the user's password
<form method="post" action="passupdate.php">
<input name="password" value =""/>
<input name"confirmedPassword" value=""/>
<input type="submit" value="Save my new password">
</form>
<?php
} else {
echo "Sorry, invalid reset link";
}
When I updated the plugin it had the number of steps I wanted.
I am using codeigniter php framework. I am suffering from the problem that all the userss password automatically get changes in database sometime, please help.
This is my reset code
function reset_now($key){
//key of fourth segment is saved on cookie
$key = $this->uri->segment(4);
//start validation
$this->form_validation->set_rules('password','Password','xss_clean|required|alpha_numeric|min_length[6]|max_length[20]|matches[password_conf]|sha1');
$this->form_validation->set_rules('password_conf','Password Confirmation','xss_clean|required|alpha_numeric|matches[password]|sha1');
if($this->form_validation->run() == FALSE){
$this->load->view('account/reset_password');
}else{
$this->db->set('password', $this->_salt.$this->input->post('password'));
$this->db->where('lostkey', $_POST['lostkey']);
$this->db->update('users');
$this->session->set_flashdata('message','Password changed, please login with new password');
redirect('account/login');
//$this->load->view('account/reset_password_complete');
}
}
You might have forgot where condition in password update sql. Please re-check your sql. Passwords will not get changed automatically. It might be trigged when someone tries to change password.
UPDATE as per the code provided
Your update where condition is,
$this->db->where('lostkey', $_POST['lostkey']);
The where clause should use the user id(the primary key of the user in database) instead using lostkey( i dont what it means, it is possible that there are multiple rows with same lostkey).
So, your where clause must be something like
$this->db->where('id', $user_id).
I want to limit the failed login attempts. For example, if a specific user attempt to login with wrong username or password 4 times, i should show the CAPTCHA 4th time instead of blocking for some specific time, and keep showing CAPTCHA unless he supplies valid username and password. Once the user has successfully logged in, the login attempt is reset to ZERO.
Is the idea of checking the username instead of IP address OK in security point of view? Can this approach be implemented without using database?, as I think I don't need to store time because i will just show recaptcha?
Please give your opinion.
You don't want to use the database for the 'number of failed logins'-check? Then just use a cookie and check it. Sure, they can remove it, but it's a hassle.
However, I suspect that you already are getting the username and password from the database, why not also fetch the last number of failed logins while you are at it?
if (isset($_POST['submit_login'])) {
if (isset($_POST['username']) && isset($_POST['password'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
// id = unique primary key
$rs = mysql_query('SELECT id,Username,Password,Failed_logins,IP_address FROM Users WHERE Username = '.$username.'');
$num = mysql_num_rows($rs);
if ($num > 0) {
// I would add a password hash here to $password, and check against the hashed Password from the database
// But let's check the clean passwords
$row = mysql_fetch_array($rs);
if ($password == $row['Password']) {
// Successful login, set session or whatever you need
// Reset failed logins
mysql_query('UPDATE Users SET Failed_logins = 0 WHERE id = '.$row['id'].'');
header('location: success.php');
} else {
// Failed password check
if ($row['Failed_logins'] > 3) {
// Redirect to captcha
header('location: captcha.php');
} else {
$ip = $_SERVER['REMOTE_ADDR'];
if ($row['IP_address'] != $ip) {
// New ip adress, reset failed logins
$failed_logins = 0;
} else {
// Increment failed logins
$failed_logins = $row['Failed_logins']+1;
}
mysql_query('UPDATE Users SET Failed_logins = '.$failed_logins.',IP_address = '.$ip.' WHERE id = '.$row['id'].' ');
} // End check Failed_logins > 3
}
} else {
// No such Username found in database
$error = 'no_such_username';
} // End username check from database
} else {
// Either username or password is missing
$error = 'incomplete_form';
} // end check for username and password
} // end main submit_login check
Something like that.
EDIT:
This is really old code and I see some problems with it now. But, at least you should always use PDO (prepared statements) for inserting data in your database.
What are you protecting?
Random user-only content, username.
Banking information (I doubt..) or other sensitive data, IP might be okay, provided you use ranges.
Are you asking how to do it, or which you should use?
You do need time, how would you otherwise determine if an login attempt has expired? If I would fail to login 4 times over a 10 year time span I would get blocked. You want to block those who attempt multiple login attempts in a short time span.
I suggest you use an database - as you will keep an detailed history of logins at the same time. But an memory based solution like memcached could also suffice.
To elaborate on which security to implement: a combination!
Combine the used username and ip address and store them into your database.
Use the login attempts on your username to directly protect your users from attempts.
Use the ip address information to observe an detect only, and take action if needed.
You should save the attempts in a database and check the user.
The best way to do this is to use databases.
You need to create a separate table in your database, which would store three variables :
(a) IP address (where the person is trying to log in)
(b) Number of login attempts
(c) date/time (or : current-timestamp)
The ONLY problem with this approach is with the first variable : IP address
What if the person is in an Internet Cafe? Or using public Wi-fi? Or Hotspot? Or, a school? office? etc, etc
If you block the IP address, it affects everybody who is trying to log into your website from that location.
This is not a problem if your website concerns something like a bank, or military installation, or the Pentagon.
But, if your website is a business (buy-and-selling, game, whatever), then blocking a specific address will only piss off your customers!
Below is a page that handles a login script and I am wondering if I have put it any security holes. I have been reading articles on protecting from injections and others and wanted to make sure that my code is secure.
It is submitted via ajax and returns JSON based on the login being correct or not.
<?php
ob_start();
session_start();
include ("config.inc.php");
include ("jsonEncode.php");
// ausername and apassword sent from form
$ausername = '';
$apassword = '';
$ausername = mysql_real_escape_string(stripslashes($_GET['username']));
$apassword = mysql_real_escape_string(stripslashes($_GET['password']));
$sql = "SELECT * FROM admin WHERE ausername='$ausername' AND apassword='$apassword' LIMIT 1";
$result = mysql_query($sql) or die(mysql_error());
$data = mysql_fetch_array($result);
$count = mysql_num_rows($result);
if($count==1){
$_SESSION['ausername'] = $ausername;
$_SESSION['apassword'] = $apassword;
$_SESSION['admin_id'] = $data['a_id'];
$a_id = $data['a_id'];
$_SESSION['LastLogin'] = $data['last_login'];
$query = "UPDATE admin SET last_login = Now() WHERE `a_id`= $a_id";
mysql_query($query);
//echo $query;
$_SESSION['aloggedin'] = "1234";
// valid
$var = array('avalid' => 1, 'ausername' => $ausername, 'apassword' => $apassword);
print php_json_encode($var);
}else{
// invalid
$var = array('avalid' => 0, 'ausername' => $ausername, 'apassword' => $apassword);
print php_json_encode($var);
}
?>
You might want to use the POST method rather than GET with the login form, otherwise their password will appear in the URL and URLs aren't very secure (they might get bookmarked or sent to another server as a referral URL, for example).
You don't need to strip the slashes. Unless you are also stripping slashes when these columns are populated, you've actually introduced a security hole -- if for whatever reason you don't have a unique constraint on the username field, and/or you have slashes in the in the stored username or password fields, and their passwords differed only by a slash, you could get one user logged in as another.
You should be using bound parameters to put user data into your SQL, not string concatenation.
Also, you should probably be storing password hashes in your database - not the original plaintext passwords.
Finally, not a security issue, but setting $ausername and $apassword to '' immediately before giving them new values is entirely pointless.
Also, don't store the password in the session. Php session data is stored in the OS tmp/temp directory by default so the data could be viewed by others. Normally, I'll just keep the username in the session and query the database when needed. That avoids problems when a user's information is changed, but the session isn't updated.
(I'm an MSSQL bod, so don't know if any of these points are irrelevant to MySQL)
This isn't really to do with security, just general observations in case helpful:
Don't use SELECT * - list the columns you want back - looks like you only need a_id & last_login. You might add a Blob in that table with their photograph in the future, or personal notes etc. - it will kill performance in all the places where you did SELECT * in the past and didn't need the picture.
I wouldn't do LIMIT 1 - I'd quite like to know if there are DUPs at this point, and raise an error.
I would put the last_login column in another table linked 1:1 with your User / password table. Its a frequent-change item, and if you decide to introduce an Audit table on the user/Password table (i.e. store the old values whenever it changes) having a frequently changing "info" column mucks that up a bit.
Personally I would want to keep the column naming convention and the SESSION / variable one the same.
admin_id / a_id, LastLogin / last_login
Personally I wouldn't store password in the session unless you need it later on. I would store something to indicate the "permissions" the user has, and then use that to decide if they can view PageX or PageY etc.
All good answers above.
Only one thing I want to add that hasn't been mentioned... I tend to fetch the account password and do a PHP comparison rather than putting the password in the query and looking if the row exists.