Im making a registration script for my site and i want to check if $_POST['username'] does already exist in db.
Is there a better, less code way of doing it? I do the same for email.
This is how it looks like now:
$checkusername = mysql_query("SELECT username FROM users WHERE username = '$_POST[username]'");
$row83 = mysql_fetch_assoc($checkusername);
if ($_POST['username'] == $row83['username']) die('Username already in use.');
Add a unique constraint onto your table:
alter table users
add unique (username)
Then, your insert or update statements will fail out:
mysql_query("insert into users (username) values ('$username')")
or die('Username exists');
Of course, a bigger issue with your code is that you aren't preventing SQL injection. Your code should be:
$username = mysql_real_escape_string($_POST['username']);
mysql_query("insert into users (username) values ('$username')")
or die('Username exists');
since you are already checking the username in the sql call, then you really just need to see if a record is returned in the php side of things
$row83 = mysql_query($checkusername);
if (mysql_num_rows($row83) == 0) die('Username already in use.');
If you set username as "unique" in your database you can just go ahead and run the insert query, which will fail (which you can handle). The same goes for email - make it "unique".
This may come in handy.
Related
I have a login form and I'm confused why my SQL Injection parameters doesn't work in here. I don't have any function or method for preventing the SQL Injection.
I made this login form for the testing of SQL injection and it's written in PHP.
Here is my code.
<?php
include("myconnection.php");
$error="";
if(isset($_POST["submit"]))
{
if($_POST["username"] == '' || $_POST["password"]== '')
{
$error='Please fill the blanks!';
}else
{
$username=$_POST['username'];
$password=$_POST['password'];
$sql="SELECT * FROM users WHERE username='$username' AND password='$password'";
$result=mysqli_query($db,$sql);
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
if(mysqli_num_rows($result)==1)
{
$login_user=$_POST["$username"];
header("location: myhome.php");
$error="Connected";
}
else
{
//$error="Incorrect Username/Password";
$message="Incorrect Credentials";
echo "<script='text/javascript'>$message</script>";
}
}
}
else
{
}
?>
I tried admin'OR'1'='1 in both username and password fields and any other possible basic injections but it doesn't work. I tried using the basic sql injection in most of working sites and it works, I'm just confused my my code doesnt accept sql injections.
And it gives me the same echo when you have an incorrect credentials.
I hope this is done for academic purposes as I have no idea why you would ever want to have this in any production websites. That being said it is probably because of the AND needing to also be true for the query to return any results. Where as if you had submitted admin'OR'1'='1 in the username field your query would look like
SELECT * FROM users WHERE username='admin'OR'1'='1' AND password='123'
That reads to me as WHERE username equals admin OR 1 equals 1 AND password equals 123. You would probably need to figure out how to also bypass that check as it will try to match password field still and vice versa the username field.
Seems odd to say but if you wanted to inject something maybe this would work in the username field injection' OR 1 LIMII 1# Which would make something like this
SELECT * FROM users WHERE username = 'injection' OR 1 LIMIT 1#' AND password = 'pass'
Essentially you are already injecting SQL, you are just not doing it in such a way that is yielding the results you want. Try echoing the query and running it directly in the mySQL CLI to see what the result set is and if it is a valid query. Maybe play around with the query there to try and obtain your intended injection.
Well i have a problem. I have a registration for for legal users and natural users, but i need to write a validation in each php file for username checking, i have no idea how to combine two table checking.
one table is called users_legal, 2nd one is users_natural. In both forms name for input field is "username".
So far i have a code that checks passwords :
if ($password == $password_re)
{
// insert into table
$sql = $db->prepare("INSERT INTO users_legal(name, reg_number, address, phone, email, username, password) VALUES(?, ?, ?, ?, ?, ?, ?);");
$sql->bind_param("sssssss", $name, $reg_number, $address, $phone, $email, $username, $password);
$sql->execute();
$sql->close();
}
After makeing a validation in register forms, i also need it in login page. I figured out how to check if there is only and only one user with that username and that password, but i have no idea how to search them between tables.
login.php code :
if($_SERVER["REQUEST_METHOD"] == "POST") {
// username and password sent from form
$myusername = mysqli_real_escape_string($db,$_POST['username']);
$mypassword = mysqli_real_escape_string($db,$_POST['password']);
$sql = "SELECT id FROM login WHERE username = '$myusername' and password = '$mypassword'";
$result = mysqli_query($db,$sql);
$row = mysqli_fetch_array($result,MYSQLI_ASSOC);
$active = $row['active'];
$_SESSION['username'] = $myusername;
$count = mysqli_num_rows($result);
if($count == 1) {
session_register("myusername");
$_SESSION['username'] = $myusername;
$_SESSION['loggedin'] = true;
header("location: www.goole.lv");
}else {
$error = "Your Login Name or Password is invalid";
}
}
One more thing : i set my mysql to utf format, var_dump says that input is allright, but in mysql it saves in unbelievuble forms, like Ķegums or Skrīvelis.
Thnx for any examples, tips or whateva u got.
When I got you right, you have two tables with users. To validate if an user has logged in successfully you look up their login credentials in the related database table.
You are asking for 'combining' these two tables. But I don't think that that's what you want. You have two separate user tables. They do not belong to each other. If you join those tables, you might have dulicate unique user ids when combining these tables.
What you could do instead is check both tables separately, first for users_legal and second for users_natural.
You should also think about using password hashes instead of plain passwords in your db. And use pdo ;)
Good luck
To solve the problem of having two different types of users I would just put them in the same table and add a value that represents the user type for example 0 = legal and 1 = natural. This will also automatically prevent two users from sharing the same username. (This will only work for sure if the database is still empty, if not you might end up with two users with the same name). For the character encoding try setting mysql to utf-8 if you haven’t done it already (instead of just utf). Also you should never save passwords in plaintext. Use the sha1 function in php to convert them to their hash value before storing them. That way even if someone gets unauthorized access to the database they still won’t know the passwords. You should also append some user specific information to the password before hashing so that even if two users share the same password their hash values will be different. To verify if it’s correct you just apply the same procedure to the input before comparing it with the hash value you have stored.
For example someone tries to log in with the name "Bob" but there is no Bob in the database. Should the user be notified there is no Bob or should should the program simply say "authentication failed" (I noticed Gmail does this)? This is partly a usability question and partly an efficiency question. As it is now the program queries the database to see if the given username exists and if it does then it queries the database again to find the password hash for the same username (redundant).
//$link is the link to the database storing passwords/usernames
if(userNameExists($uName, $link))
{
if(passwordCorrect($uName, $pass, $link))
echo 'log in successful!';
else
echo 'can\'t log in';
}
else
{
echo 'username doesn\'t exist!';
}
/*This function checks to see if the username exists
INPUT: the userName to check for and a link to the database
OUTPUT: true if username exists
*/
function userNameExists($userName, $link)
{
$result = mysqli_query($link, 'SELECT `userid`
FROM `login`
WHERE `userid` = \''.$userName.'\' LIMIT 1');//need to look into uses of backticks, single quotes, double quotes
return mysqli_num_rows($result) == 1;
}
/*This function checks the password for a given username
INPUT: the userName and password the user entered, and a link to the database
OUTPUT: true if the given password matches the one in the database
*/
function passwordCorrect($userName, $givenPassword, $link)
{
$result = mysqli_query($link, 'SELECT `password`
FROM `login`
WHERE userid = \''.$userName.'\' LIMIT 1');
$retrievedPassword = mysqli_fetch_array($result);
if(password_verify($givenPassword, $retrievedPassword['password']))
return true;
else
return false;
}
Should I instead only use passwordCorrect() and if mysqli_query() returns false this implies the username does not exist (admittedly I don't like these solutions because it could mean something else has gone wrong, doesn't it?)?
You should not provide details why the login failed (user does not exists or password is wrong), as this increases security. Unless usernames are visible when one is not logged in (which is actually insecure and should not be the case..!)
Advantage is that you indeed can use a single query to get the hash for the given username. If you do not get a result, the username is wrong (and the login failed), otherwise you can (directly) check the hash (to see if the password is wrong).
Roughly speaking there are two basic points to this story that you can consider
Providing specific information may improve usability because the user then knows what piece of information he provided was erroneous
But providing specific information also allows for potential abuse. If you specifically return if a username did not exist, the opposite might alert a hacker that a username does exist and he may use that information to more effectively use brute force techniques to crack logins
What best suits your situation will always be a trade off but often it is advised to omit specific information for the aforementioned security reasons
I'm using mysql and php for registration on my web-site. Registration is ok. Mysql do queries immediately. But in login there strange things begin to happen. I insert a test in my php code to insert test row to database. First test code inserted immediately, but 2nd was inserted after series of refresh and relog actions only after 10 minutes. The 3rd test query is the same-after approximately 10 minutes after 2nd query.
Here is login code:
<?php
session_start();
if(isset($_SESSION['id'])){
echo 'You have logged in.';
echo $_SESSION['id'];
}
else {
$email=$_POST['email'];
$password=$_POST['password'];
$db=new mysqli('','','','');
if (mysqli_connect_errno()) {
echo 'Unable to connect to database: '.mysqli_connect_error().'. Please e- mail our system administrator. We will fix this error as soon as possible. Thanks for patience and understanding. ';
exit();
}
//TEST QUERY
$query="insert into test values(3, 'test')";
$result=$db->query($query);
//LOGIN QUERY
$query="select id from users where email='$email' and password='$password'";
$result=$db->query($query);
if ($result->num_rows==0) {
echo 'Incorrect email or password.';
}
else {
$row=$result->fetch_assoc();
$_SESSION['id']=$row['id'];
echo 'You have logged in.';
echo $_SESSION['id'];
//THIS TEST QUERY IS NOT IMPLEMENTED
$query="insert into test values(1, test)";
$result=$db->query($query);
}
}
?>
Where is mistake?
Test table consists of 2 columns: id (medium int, primary key, unsigned) and test(text)
Thanks in advance.
Sounds like the cookie could be expiring after 10 minutes. Run echo session_cache_expire(); to see what your expiration time is set to. More details at http://php.net/manual/en/ref.session.php
insert into test values(1, test)
-- test -- needs quotes or you are going to get an error that the column test doesn't exist (unless it does). If it does exist, it's probably going to be empty, as mysql probably doesn't know what you mean by test -- maybe your version thinks it's a constant or something.
If you posted what the table structure of your test table is, that would help solve it probably.
This looks suspicious to me.
$query="insert into test values(3, 'test')";
Is it trying to set the ID of every row inserted to 3? ID's have gotta be unique.
EDIT:
This probably won't fix your problem, but it will make your life easier by not forcing you to manually change ID's each time.
INSERT INTO test SET <colname>='test'
where <colname> is the name of the column that "test" is going into.
Just a little security hint: your SQL queries are very dangerous as they are prone to SQL injection attacks. See the Wikipedia article for alternatives ...
EDITThanks to the comments below it has been figured out that the problem lies with the md5, without everything works as it should.
But how do i implent the md5 then?
I am having some troubles with the following code below to login.
The database and register system are already working.
The problem lies that it does not find any result at all in the query.
IF the count is > 0 it should redirect the user to a secured page.
But this only works if i write count >= 0, but this should be > 0 , only if the user name and password is found he should be directed to the secure (startpage) of the site after login.
For example root (username) root (password) already exists but i cannot seem to properly login with it.
<?php
session_start();
if (!empty($_POST["send"]))
{
$username = ($_POST["username"]);
$password = (md5($_POST["password"]));
$count = 0;
$con = mysql_connect("localhost" , "root", "");
mysql_select_db("testdb", $con);
$result = mysql_query("SELECT name, password FROM user WHERE name = '".$username."' AND password = '".$password."' ")
or die("Error select statement");
$count = mysql_num_rows($result);
if($count > 0) // always goes the to else, only works with >=0 but then the data is not found in the database, hence incorrect
{
$row = mysql_fetch_array($result);
$_SESSION["username"] = $row["name"];
header("Location: StartPage.php");
}
else
{
echo "Wrong login data, please try again";
}
mysql_close($con);
}
?>
The best thing you can do in such situations is trying to find out where the problem lies.
So, you could proceed by steps and do the following:
1) start your script with a print_r($_POST), to see what variables are passed by post (by absurd, the problem might even be related to the 'send' guard parameter you have ..IE a form being sent through get)
2) Assign your query to a variable (...and don't forget to escape parameters!) and print it to screen; and then exec it on mysql (or phpmyadmin) to see what results they give.
As a side note, as someone already pointed out, this code might be subject to SQL-injection, so you might consider using prepared statements; see here: quick intro
Your login code is good.
But you also need to use md5() function BEFORE storing the password in the database. So when you are inserting the user record in the DB , apply the md5() to the password , save in the DB. Now when you will try to find the record on login, it will match correctly.
You should rewrite this with mysqli or PDO and using a newer hash function as well as a salt. MD5 is very widely used and is a target for crackers.