I'm having a problem with a PHP-Script, where I want to check, if the MySQL-Logindata are valid. I found somewhere the mysql_ping() function, but it doesn't work as it should, because it returns in every case true, even if the inserted data are totally wrong. How do I solve it?
$verbindung = mysql_connect($_POST["mysql_host"], $_POST["mysql_user"],
$_POST["mysql_pwd"]);
if (!mysql_ping($verbindung)) {
$break = true;
}
else {
// Check here also via SQL, if database $_POST["mysql_db"] exists
}
This already is more complex than it needs to be and should do the correct thing. The reason why all usernames work quite likely is that MySQL by default has an anonymous user ''#'localhost' which accepts any username. Probably you want to remove that user. (DROP USER ''#'localhost', be sure you can login as other user before doing that, use SHOW GRANTS to see which user you are using)
For simplification mind that the connect cal will fail if there is something wrong, so you wont need that ping call. ping can be used if you have a longer living connection and you want to check whether the connection is still working.
A simple form for the check might look like this:
$verbindung = new mysqli($_POST["mysql_host"], $_POST["mysql_user"], $_POST["mysql_pwd"]);
if (!$verbindung) {
echo "Wrong settings";
}
Mind that I changed to the mysqli insterface. the old mysql extension in PHP providing the mysql_* functions is deprecated and shouldn't be used anymore.
I actually found out a nicer solution with the mysqli_connect_errno() function and a requirement of inputs from the database name and the user name.
$verbindung = #mysqli_connect((!empty($_POST["mysql_host"]) ? $_POST["mysql_host"] : 'localhost'),
$_POST["mysql_user"], $_POST["mysql_pwd"], $_POST["mysql_db"]);
if (mysqli_connect_errno() || empty($_POST["mysql_user"]) || empty($_POST["mysql_db"])) {
$break = true;
}
Related
So, I've been having alot of bother with a Paypal IPN script i'm working on - I'm a bit of an idiot when it comes to PHP.
I've got a script called glob.inc.php, which connects to my database and checks if a user is premium, however when the script is runs I just get this:
Warning: mysql_result(): supplied argument is not a valid MySQL result
resource in
/public_html/fts/rs_ipn/glob.inc.php
on line 11
This is the script for glob.inc.php:
<?php
session_start();
// database connection
mysql_connect('XXXXXXXX','XXXXXXXX');
mysql_select_db('XXXXXXXX');
// premium check function
function is_premium() {
$premium_query = mysql_query("SELECT 'premium' FROM 'users' WHERE 'user_id'='".$_SESSION['user_id']."'");
$premium = mysql_result($premium_query, 0, 'premium');
if ($premium =='1') {
return true;
} else {
return false;
}
}
?>
I've tried everything I can think of, but am having no joy! May be interested to know that the script fails to successfully check if the user is premium. Sessions are created ok though, and the database connection is fine.
Hope you can help!
Did you check that the query was executed properly?
See this example.
Also, as mentioned in the comments, do not use mysql_* functions, use mysqli_* or PDO instead.
You need to fetch the result instead of trying to access the resource.
Please refer to the documentation before asking question.
I am using WYSIWYG Webbuilder 8 to construct a website. Part of the website will be restricted access to registered users only. To this end I have created a MySQL database. I also have a sign-up form. When a new user wishes to sign-up I would like to have the username automatically checked against the database to make sure it doesn't already exist. I intend doing this using an AJAX function as the WYSIWYG software has this option built in. What I need to build myself and this is where I'm struggling is the validate.php that the AJAX command will go to.
I have something like this at present (please excuse my ignorance!):
<?php
$username = $_POST['data'];
// TODO: lookup username in database...
if ($username == 'user')
{
echo "true";
}
else
{
echo "false";
}
?>
I have no real idea if this is adequate or secure. I have been reading some scary stuff about sql injection and other black arts involving the use of forms and I'd like to avoid pitfalls if possible.
Would some kind soul please have a look at my request and help me out? I'm not a programmer by any stretch of the imagination and I'm way out of my depth here.
Thanks in advance for your help
You want to use something that will handle the chatter between your application and the database for you. One of the best tools available for this today is the PDO library, specifically PDO-MySQL for your usage. It will handle escaping and SQL injection issues for you by using parameterized (prepared) statements
Here's an example of connecting to a database and issuing a query in MySQL
$db = new PDO('mysql:host=localhost;dbname=dbname;charset=UTF-8', 'username', 'password');
$statement = $db->prepare('SELECT user_id FROM users WHERE username = :username LIMIT 1');
$statement->bindValue(':username', $_POST['data']);
$statement->execute();
if (false == $userId = $statement->fetchColumn()) {
// No matching username was found in the database
} else {
// A matching username was found in the database
// $userId contains the matching user ID
}
Knowing how to pass this back to your JS/AJAX integration could be dependent on what framework (if any) you are using and what format you would like that data in
So I connect to my MySQL database using the following code:
function dbConnect($h,$u,$p,$n) {
if (!$con = #mysql_connect($h,$u,$p)) {$err = err("There is a problem connecting to the database. ".mysql_error());}
else if (!#mysql_select_db($n,$con)) {$err = err("The database \"{$n}\" could not be found. Check your spelling, make sure the database exists, and that your database credentials allows you access to this database.");}
return (isset($err)) ? $err : "";
}
The problem is, if they put in a wrong username, mysql_connect will not see anything wrong with it and try to connect to the database, which outputs an error for the mysql_select_db().
So I found this link. Now normally removing the "any" user would be doable but I'm creating a phpMyAdmin-like tool and will be connecting to different databases with all types of configurations. How can I tell which username can actually connect? And how can I differentiate between the database name not existing and the username not having access to it?
use mysql_errno()
see error codes here
As part of a PHP web application, I'm querying a MySQL database using mysqli and prepared statements.
I've used exactly the same code on a few queries and it works, but on one particular query, it always returns an empty record set. I've run exactly the same query from the MySQL command line, and it correctly returns the result. I've checked the parameters being passed in, and they're fine.
I've spent the best part of a day trying to figure out why I'm always getting an empty record set with no errors or warnings. I've got PHP's errors set to display on the page, and I've got them set to E_ALL|E_STRICT. I still don't get any warnings or errors.
I've tried all the obvious things, like making sure I can actually connect to the database, checking the parameters that are being passed in, and making sure the row I'm trying to return actually exists in the database. I've had var_dump()s and die()s all over the page to check what's coming back, and it's always a legitimate, but empty, recordset.
function salt() {
return("I've removed my salt from this sample code");
}
function openDatabase() {
$conn = new mysqli("127.0.0.1", "username", "password", "database")
or die("Error: Could not connect to database.");
return($conn);
}
function checkUserCredentials($username, $password) {
$goodPassword = md5(salt().$username.$password);
$conn = openDatabase();
$query = $conn->stmt_init();
$query->prepare("SELECT id FROM users WHERE email = ? AND passwordHash = ?")
or die('Problem with query');
$query->bind_param("ss", $username, $goodPassword)
or die('Error binding parameters');
$query->execute() or die("Could not execute");
$query->bind_result($col1) or die ("Could not bind result");
if ($col1 !== 0) {
die("Authentication Complete");
} else {
die("Authentication Failure! Number of Rows: ".$query->num_rows." Username: " . $username . " Password Hash: " . $goodPassword);
}
}
Any feedback is appreciated. I'm sure I'm missing something simple, but if I didn't shave my head I'd be tearing my hair out right now.
Thanks
I'm not familiar with the mysqli library (I usually use PDO which provides a very similar cross platform API) so I can't immediately see any problem. However, you might try watching the mysqld log. See here for info:
http://dev.mysql.com/doc/refman/5.1/en/query-log.html
By tailing the log, you should be able to see the exact query that was submitted.
One final note, I notice you're using a fixed salt value. Wouldn't it be better to generate this value randomly each time you need it and then store it in the users table? Generally, a salt is not intended to be secret, it's just there to prevent people precomputing tables of passwords using the hash algorithm that you use.
In case anyone else runs into similar issues, it really helps if you run fetch() on your mysqli_stmt object.
In my code above, the solution looks like this:
$query->bind_result($col1) or die ("Could not bind result");
$query->fetch(); // <--- How could I forget to do this?
if ($col1 !== 0) {
return true;
} else {
return false;
}
Added on behalf of OP
Can anyone see anything wrong with this login script:
public function login($username, $pass, $remember) {
// check username and password with db
// else throw exception
$connect = new connect();
$conn = $connect->login_connect();
// check username and password
$result = $conn->query("select * from login where
username='".$username."' and
password=sha1('".$pass."')");
if (!$result) {
throw new depException('Incorrect username and password combination. Please try again.');
} else {
echo $username, $pass;
}
To explain:
At the moment the script is allowing anything through. In other words the query is returning true for any username and password that are passed to it.
I've put the echo statement just as a check - obviously the script would continue in normal circumstances!
I know that the connect class and login_connect method are working because I use them in a register script that is working fine. depException is just an extension of the Exception class.
The function login() is part of the same class that contains register() that is working fine.
I know that the two variables ($username and $pass) are getting to the function because the echo statement is outputting them accurately. (The $remember variable is not needed for this part of the script. It is used later for a remember me process).
I'm stumped. Please help!
UPDATE
Thanks for those responses. I was getting confused with what the query was returning. The complete script does check for how many rows are returned and this is where the checking should have been done. Everything is now working EXCEPT for my remember me function. Perhaps someone could help with that?!?! Here is the full script:
public function login($username, $pass, $remember) {
// check username and password with db
// else throw exception
$connect = new connect();
$conn = $connect->login_connect();
// check username and password
$result = $conn->query("select * from login where
username='".$username."' and
password=sha1('".$pass."')");
if (!$result) {
throw new depException('Incorrect username and password combination. Please try again.');
}
if ($result->num_rows>0) {
$row = $result->fetch_assoc();
//assign id to session
$_SESSION['user_id'] = $row[user_id];
// assign username as a session variable
$_SESSION['username'] = $username;
// start rememberMe
$cookie_name = 'db_auth';
$cookie_time = (3600 * 24 * 30);*/ // 30 days
// check to see if user checked box
if ($remember) {
setcookie ($cookie_name, 'username='.$username, time()+$cookie_time);
}
// If all goes well redirect user to their homepage.
header('Location: http://localhost/v6/home/index.php');
} else {
throw new depException('Could not log you in.);
}
}
Thanks very much for your help.
UPDATE 2!
Thanks to your help I've got the main part of this script working. However, the remember me bit at the end still doesn't want to work.
Could someone give me a hand to sort it out?
$username, $pass and $remember are all short variable names that I assigned before passing them to the function to save writing $_POST['username'] etc. everytime. $remember refers to a checkbox.
What does $conn->query() return, a MySQL resource object like mysql_query() does? If so then it'll always compare "true". mysql_query() only returns FALSE if the query completely fails, like it has a syntax error or a table doesn't exist.
To check if you got any results you need to try to fetch a row from the result set and see if you get anything, via whatever your equivalent of mysql_fetch_row() is.
Important: Your script is vulnerable to SQL injection attacks, or even just odd usernames like o'neil with an apostrophe. You should escape all variables in a query with mysql_real_escape_string() (or equivalent) to make sure your query doesn't get messed up by special characters. Or, even better, use prepared statements which look like
select * from login where username=? and password=sha1(?)
Re: UPDATE
Variables from a form are available via either $_GET or $_POST, depending on which method was used to submit the form. Try if (isset($_POST['remember'])) to see if that check box was checked.
Important: I see that you tried to use a bare $remember to see if the check box was checked. That suggests to me that you are trying to take advantage of the register_globals feature in PHP which makes your GET and POST variables accessible via regular variable names. If that is the case you should heed the warning in the PHP manual!
WARNING
[register_globals] has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 6.0.0. Relying on this feature is highly discouraged.
Use $_GET and $_POST instead. I could tell you how to make if ($remember) work, actually, but given the inherent evil-ness of register_globals I'm not gonna! ;-)
Your query is open for sql-injections...
SELECT * FROM users WHERE
username = '' OR 'a' = 'a'
AND password =
sha1('guessAnyPassword')
I'd also check your result, and base the action on how many records were returned.
if (mysql_num_rows($result) > 0)
In php most queries only return False if there was an error executing them. Your query is returning a value, probably an empty array of values. This is not a false value as far as your if statement is concerned.
Check how many rows are returned. The function to do this will depend on your abstraction layer (connect class etc...)