[PHP] RE:[PHP] login problem fixed!!

2004-03-25 Thread Andy B
[snip]
please note this will only catch invalid queries. To catch the event
of the query being perfectly fine, but nothing coming back, just check
the values of num_rows or affected_rows (depending on the query).

[/snip]

um?? this way doesnt work for some strange reason... testing
affected_rows returns always with 0 so: if(mysql_affected_rows()==0){...}
will always get ran even if the query itself returned an invalid user
login...
num_of_rows will always return true and never false i guess because when
$result (the query itself) is invalid or returns the fact that the user
typed a wrong username and or password the db server returns NULL, false or
rightfully 0. thus the error:
num_of_rows() is not a valid resource type in:..login.php error

so as far as i know i have to test the literall existance of the $result
resource being true (a real login) or false (the login failed)...

at this point i cant test for $_SESSION['username'] because it hasnt been
registered yet...

anyhow..off my soap box

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] RE:[PHP] login problem fixed!!

2004-03-25 Thread Richard Davey
Hello Andy,

Thursday, March 25, 2004, 9:53:05 AM, you wrote:

AB um?? this way doesnt work for some strange reason... testing
AB affected_rows returns always with 0 so:
AB if(mysql_affected_rows()==0){...}

It depends on your query. If you are doing a SELECT query then you
cannot use affected_rows, you must use num_rows instead. If you are
doing an UPDATE or INSERT query then swap that over.

AB num_of_rows will always return true and never false i guess because when

mysql_num_rows will never return true OR false because it doesn't return a
boolean, it returns a value, so you cannot check its contents like
this.

AB $result (the query itself) is invalid or returns the fact that the user
AB typed a wrong username and or password the db server returns NULL, false or
AB rightfully 0. thus the error:
AB num_of_rows() is not a valid resource type in:..login.php error

mysql_query ONLY returns a FALSE if the query fails for SELECT queries
(and show/explain/describe, but that's not relevant to this).

If your query is perfectly valid but simply returns no data, you can
only check for this with mysql_num_rows.

Your logic sequence should be as follows:

1. Send query to MySQL

2. Check if mysql_errno == 0
If it DOESN'T, your query had an error, so find out what it was by
echoing out mysql_error() and quitting gracefully.

3. If mysql_errno == 0 then your query ran perfectly, so...

4. Check value of mysql_num_rows. If == 0 then simply no data was
returned, so handle the error accordingly. If value == 1 then you know
you've got the data back that you wanted.

For INSERT/UPDATE queries substitute mysql_num_rows in the above for
affected_rows, principle is the same though - but be careful when
comparing your data types for affected rows.

-- 
Best regards,
 Richard Davey
 http://www.phpcommunity.org/wiki/296.html

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP] re:[PHP] login problem fixed!!

2004-03-25 Thread Andy B
So, just for the sake of me getting this right, it would be better code if i
had the code like this:

?
$UserExists=mysql_query(select * from users where
username='$_POST[username]' and pwd=md5($_POST[password]));

//since query is done see if the user exists
if($UserExists) {
ExistingUserCanDoSomething(); }
else {
YouCantDoAnythingIfYouDontExist(); }
?

forgive the odd severely long redundant example names but... im sure that is
better than what i had before...

let me know if i got the right idea...

and $UserExists in this example is either true or false because empty set
in mysql isnt even a number it = NULL

echo $UserExists;//prints 0 if false and 1 if true
//at least in this instance of it (normally it would return total rows
matched)

at the point of logins i dont care about the # of rows it will alwas return
0 or 1 so  true/false is best for me right now. when i create the user
generater then i will need to check for multiple usernames/passwords (2
users cant have the same pwd or id)...

anyways...off my box again

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] re:[PHP] login problem fixed!!

2004-03-25 Thread Richard Davey
Hello Andy,

Thursday, March 25, 2004, 10:43:54 AM, you wrote:

AB So, just for the sake of me getting this right, it would be better code if i
AB had the code like this:

AB ?
AB $UserExists=mysql_query(select * from users where
AB username='$_POST[username]' and pwd=md5($_POST[password]));

AB //since query is done see if the user exists
AB if($UserExists) {
AB ExistingUserCanDoSomething(); }
AB else {
AB YouCantDoAnythingIfYouDontExist(); }
?

Do you actually need to bring back the user data? What I mean is,
you're selecting * from the users table and doing nothing with it
other than worrying if the query was successful or not.

It would make far more sense if you just did this:

SELECT COUNT(username) AS hits FROM users WHERE ...

Providing your query syntax is good this will always return a value in
hits. A zero means no users, anything above and you've got a live
one.

Also - I doubt I need to mention this, but you're injecting POST
variables directly into a SQL query. I hope your example above was
just that and isn't the actual way you're doing it?

AB and $UserExists in this example is either true or false because empty set
AB in mysql isnt even a number it = NULL

$UserExists in your example will never be TRUE, it can only ever be
FALSE. mysql_query does not, under any circumstances, return a boolean
TRUE value. It either returns a FALSE (if it was a select query) or a
*resource identifier* regardless of empty sets.

Sometimes if this resource identifier equals the value of 1 then a
loose comparison to true might exist, but only because PHP is determining
this value as such, not because it really is a true boolean value.

In the example above, providing all the data is given (username and
password) the query will return what appears to be TRUE regardless
of what happens. Imagine you have a user bob in your database and
his password is hi, look at the two following queries:

SELECT * FROM users WHERE username='bob' AND password='hi'
SELECT * FROM users WHERE username='bob' AND password='incorrect'

Both of them will make mysql_query return a resource identifier
because they are both correct from a syntax point of view. But in
actual fact they're telling you two completely different things.

Without doing a COUNT or knowing how many rows the query returned, you
cannot determine if the user does already exist or not, all you can
tell is if your query worked and an invalid user does not = an invalid
query.

-- 
Best regards,
 Richard Davey
 http://www.phpcommunity.org/wiki/296.html

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP] re:[PHP] login problem fixed!!

2004-03-25 Thread Andy B
Do you actually need to bring back the user data? What I mean is,
you're selecting * from the users table and doing nothing with it other than
worrying if the query was successful or not.

ops!! I forgot to mention that the username is used elsewhere in a different
file somewhere (to verify the session exists and stuff). thats the only
thing directly used elsewhere... as far as the password thing goes it needs
to know if they put in the right username and password (i.e. a row that has
the username/password they put in).

It would make far more sense if you just did this:

SELECT COUNT(username) AS hits FROM users WHERE ...

dont know because then how would i verify that the valid user was logged in
or if they typed the wrong stuff in??

Providing your query syntax is good this will always return a value in
hits. A zero means no users, anything above and you've got a live
one.

very true...might come in handy for the register a user part

Also - I doubt I need to mention this, but you're injecting POST
variables directly into a SQL query. I hope your example above was
just that and isn't the actual way you're doing it?

yikes!! good thing this is just a testing site...how to insert them if
$_POST isnt the right way then??

and $UserExists in this example is either true or false because empty set
in mysql isnt even a number it = NULL
$UserExists in your example will never be TRUE, it can only ever be
FALSE. mysql_query does not, under any circumstances, return a boolean
TRUE value. It either returns a FALSE (if it was a select query) or a
*resource identifier* regardless of empty sets.

Can we disagree here? if i take my original query (at the top of this email)
and assign the result of it to a variable $UserExists like we did above and
test it:
if($UserExists) {//assuming the server found anything to start with
echo $UserExists;
//fortunately the server found a match somewhere because
//the result of printing $UserExists is Resource id #4
} else {//what if the server couldnt find a valid row??
echo $UserExists;//results in a blank screen assuming the
//server couldnt create the resource id because of no valid
//matching rows
}
on the other hand if i didthis:
if(num_of_rows($UserExists){
echo num_of_rows($UserExists);//will get 1
} else {
echo num_of_rows($UserExists);//will get: warning: not a
//valid resource identifier for num_of_rows
}

now if i just did: select * from users for num_of_rows i would get 3 for an
answer because there are 3 rows in the table... and the else part would
never be used...

Sometimes if this resource identifier equals the value of 1 then a loose
comparison to true might exist, but only because PHP is determining this
value as such, not because it really is a true boolean value.

if that is so, then how do you explain the above??

In the example above, providing all the data is given (username and
password) the query will return what appears to be TRUE regardless
of what happens. Imagine you have a user bob in your database and
his password is hi, look at the two following queries:

again, explain the above...

SELECT * FROM users WHERE username='bob' AND password='hi'
SELECT * FROM users WHERE username='bob' AND password='incorrect'

different for sure...if your saying that i would still get a resource id
from both of those on my example then why does it somehow know the
difference?

Both of them will make mysql_query return a resource identifier

not if the comparison between the username/pwd from the form and the db are
different...then they wouldnt be the same thing (thats why i compare the
username against the password)

because they are both correct from a syntax point of view. But in
actual fact they're telling you two completely different things.

agree but im not testing the syntax

Without doing a COUNT or knowing how many rows the query returned, you
cannot determine if the user does already exist or not, all you can
tell is if your query worked and an invalid user does not = an invalid
query.

sorry for repeating but somehow it knows the difference...

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] re:[PHP] login problem fixed!!

2004-03-25 Thread Richard Davey
Hello Andy,

Thursday, March 25, 2004, 11:57:09 AM, you wrote:

AB SELECT COUNT(username) AS hits FROM users WHERE ...

AB dont know because then how would i verify that the valid user was logged in
AB or if they typed the wrong stuff in??

Because it works like this:

SELECT COUNT(username) AS hits FROM users WHERE username='$u' AND
password='$p'

So.. if hits = 0, then no user with that username and password
combination exists.

If hits = 1 (or more!) then the user exists and their password
matches.

MySQL will run a COUNT query much faster than a SELECT, especially if
you have the main columns indexes.

AB yikes!! good thing this is just a testing site...how to insert them if
AB $_POST isnt the right way then??

Extract the values before-hand:

$username = $_POST['username'];

Now run tests on $username.

For example - should it be a minimum of 3 characters? If so, use
strlen to test this. Should it most certainly not contain HTML? Then
run it through strip_tags. Remove any extra spaces that might be
entered with trim(). Etc etc - you get the idea :) The final $username
can be fed into your query far more safely than before.

AB Can we disagree here? if i take my original query (at the top of this email)
AB and assign the result of it to a variable $UserExists like we did above and
AB test it:
AB if($UserExists) {//assuming the server found anything to start with
AB echo $UserExists;
AB //fortunately the server found a match somewhere because
AB //the result of printing $UserExists is Resource id #4

This doesn't mean the server found a match, it means your query didn't
have any SQL syntax errors in it. An empty set is still a valid
resource, but it doesn't mean the given user does (or does not) exist.

AB now if i just did: select * from users for num_of_rows i would get 3 for an
AB answer because there are 3 rows in the table... and the else part would
AB never be used...

You're not counting how many users are in the table, you're counting
to see if the username and password you gave exists, like so:

SELECT * FROM users WHERE username='$username' AND
password='$password'

Then you check mysql_num_rows.

It will equal 0 if no user was found matching your combination, or it
will return a number. If you have set your table so that Username must
be unique (which would be a sensible thing to do) then it could only
ever return a 0 or a 1.

AB Sometimes if this resource identifier equals the value of 1 then a loose
AB comparison to true might exist, but only because PHP is determining this
AB value as such, not because it really is a true boolean value.

AB if that is so, then how do you explain the above??

Like I said, PHP is turning your resource identifier into a boolean
and assuming anything  0 is TRUE.

AB not if the comparison between the username/pwd from the form and the db are
AB different...then they wouldnt be the same thing (thats why i compare the
AB username against the password)

The MySQL query function doesn't care about the query itself, it's
just a means to pass it to the database. The result doesn't contain
any row information at all, just a resource which PHP uses to retrieve
the data via further functions.

See the following code I just wrote to double-check this:

First I created a MySQL database + table as such:

CREATE DATABASE test
CREATE TABLE `users` (`username` VARCHAR (30), `password` CHAR (32)) 
INSERT INTO users (username, password) VALUES ('rich', 
'e1bfd762321e409cee4ac0b6e841963c')
INSERT INTO users (username, password) VALUES ('andy', 
'81c3b080dad537de7e10e0987a4bf52e')

There we have 2 users (rich and andy), the passwords are MD5 hashes of
php and mysql. I.e. the password for rich is php and andy is
mysql.

You can save the following HTML/PHP into a file somewhere in your web
directory, it should run without modification other than perhaps the
MySQL server/username/password.

-- Cut from here --
html
head
titleMySQL Test/title
/head

body

form action=?=$_SERVER['PHP_SELF']? method=post
Username: input type=text name=usernamebr
Password: input type=text name=passwordbr
input type=submit
/form

?php
mysql_connect('localhost','root','');
mysql_select_db('test');

$username = $_POST['username'];
$password = $_POST['password'];

$sql = SELECT * FROM users WHERE username='$username' AND 
password=MD5('$password');

if (isset($_POST['username']))
{
$result = mysql_query($sql);
echo $result . br;
}

echo pre;
print_r($_POST);
echo /pre;

echo Rows Returned:  . mysql_num_rows($result) . br;

echo Comparing \$result to TRUE: if (\$result) : br;
if ($result)
{
echo Valid user;
} else {
echo Error?;
}
?
/body
/html
-- End here --

Now if what you're saying is correct, the final if result() block
should only print valid user if the user exists in the 

[PHP] re:[PHP] login problem fixed!!

2004-03-25 Thread Andy B
if ($result)
{
echo Valid user;
} else {
echo Error?;
}
?
/body
/html
-- End here --

Now if what you're saying is correct, the final if result() block
should only print valid user if the user exists in the database,
right?

yup and believe it or not if($result) only returns true if a valid
username/password row can be found otherwise it returns a non existing
resource

For me it'll print valid user no matter what I do because the query is
always valid and that is all it's checking.

hmmm interesting... in your example of usernames here, when i type andy for
username and mysql for password it says valid user. now say i type andy
for a username and junk for a password it will now say error? because in
mysql's mind set there isnt any row anywhere that exists with andy for a
username and junk for a password. now take it the other way around: i type
useless for a username and mysql for a password and then it still says:
error?...
it seems that no matter what i do (unless you directly spoof the mysql
server) it cannt be fooled at all... at this point it is acting like it is
indistructable (i know what a wild dream) but have to have one for a min ...
in any case i cant find any loop holes in it anywhere... the only thing i
see i can do to reduce risk of hacks or possible outside interference is to
turn $result in your example into a session var $_SESSION['result']. since
$result can be changed from the query string from a link (wait testing...)
well doesnt exactly work but crashes it instead being a global like that...

If I enter a valid username and password combo the result is reflected
in mysql_num_rows, as shown in the code.

yup...it does on mine too... just like you say

Unless I have missed something significant from your original code/query
I'm at a complete loss as to how the above can give you any kind of
different result?

thats a good question i cant even answer...




-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] re:[PHP] login problem fixed!!

2004-03-25 Thread Richard Davey
Hello Andy,

Thursday, March 25, 2004, 1:17:54 PM, you wrote:

AB yup and believe it or not if($result) only returns true if a valid
AB username/password row can be found otherwise it returns a non existing
AB resource

Absolutely fascinating, I have never seen a MySQL server behave like
this. Could you post which version of MySQL you're using and perhaps
the MySQL part of phpinfo()? There must be something *somewhere* that
controls this behaviour.

All I can say for certainty is that if I uploaded your code onto my
web host, it'd fail. So long as you're building this in a controlled
environment and you know where it's going to go when it's live, then I
guess you can exploit this to its full potential.

-- 
Best regards,
 Richard Davey
 http://www.phpcommunity.org/wiki/296.html

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP] re:[PHP] login problem fixed!!

2004-03-25 Thread Andy B
Absolutely fascinating, I have never seen a MySQL server behave like
this. Could you post which version of MySQL you're using and perhaps
the MySQL part of phpinfo()? There must be something *somewhere* that
controls this behaviour.

PHP Version 4.0.4pl1
Linux noir.propagation.net 2.0.36 #5 Wed Dec 16 18:09:02 CST 1998 i686
unknown
Apr 10 2001

Configure Command
'./configure' '--with-apache=../apache_1.3.19'
'--with-config-file-path=/etc' '--with-msql' '--without-gd'

PHP Core

Table with 3 columns and 59 rows

Directive
Local Value
Master Value

allow_call_time_pass_reference
On
On

allow_url_fopen
1
1

arg_separator



asp_tags
Off
Off

auto_append_file
no value
no value

auto_prepend_file
no value
no value

browscap
no value
no value

default_charset
no value
no value

default_mimetype
text/html
text/html

define_syslog_variables
Off
Off

disable_functions
no value
no value

display_errors
On
On

display_startup_errors
Off
Off

doc_root
no value
no value

enable_dl
On
On

error_append_string
Off
Off

error_log
no value
no value

error_prepend_string
Off
Off

error_reporting
no value
no value

expose_php
On
On

extension_dir
/usr/local/lib/php/extensions/no-debug-non-zts-20001214
/usr/local/lib/php/extensions/no-debug-non-zts-20001214

file_uploads
1
1

gpc_order
GPC
GPC

highlight.bg
#FF
#FF

highlight.comment
#FF8000
#FF8000

highlight.default
#BB
#BB

highlight.html
#00
#00

highlight.keyword
#007700
#007700

highlight.string
#DD
#DD

html_errors
On
On

ignore_user_abort
Off
Off

implicit_flush
Off
Off

include_path
.:/usr/local/lib/php
.:/usr/local/lib/php

log_errors
Off
Off

magic_quotes_gpc
On
On

magic_quotes_runtime
Off
Off

magic_quotes_sybase
Off
Off

max_execution_time
30
30

open_basedir
no value
no value

output_buffering
Off
Off

output_handler
no value
no value

post_max_size
8M
8M

precision
14
14

register_argc_argv
On
On

register_globals
On
On

safe_mode
Off
Off

safe_mode_exec_dir
1
1

sendmail_from
no value
no value

sendmail_path
/usr/sbin/sendmail -t -i
/usr/sbin/sendmail -t -i

short_open_tag
On
On

SMTP
localhost
localhost

sql.safe_mode
Off
Off

track_errors
Off
Off

upload_max_filesize
2M
2M

upload_tmp_dir
no value
no value

user_dir
no value
no value

variables_order
no value
no value

y2k_compliance
Off
Off
table end

mysql

Table with 2 columns and 7 rows

MySQL Support
enabled

Active Persistent Links
0

Active Links
0

Client API version
3.23.22-beta

MYSQL_INCLUDE


MYSQL_LFLAGS


MYSQL_LIBS

table end

Table with 3 columns and 9 rows

Directive
Local Value
Master Value

mysql.allow_persistent
On
On

mysql.default_host
no value
no value

mysql.default_password
no value
no value

mysql.default_port
no value
no value

mysql.default_socket
no value
no value

mysql.default_user
no value
no value

mysql.max_links
Unlimited
Unlimited

mysql.max_persistent
Unlimited
Unlimited
table end

interesting...seems to be pretty much the default install of all of it
but
All I can say for certainty is that if I uploaded your code onto my
web host, it'd fail. So long as you're building this in a controlled
environment and you know where it's going to go when it's live, then I
guess you can exploit this to its full potential.

i always fully test my code before i run it

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] re:[PHP] login problem fixed!!

2004-03-25 Thread Richard Davey
Hello Andy,

Thursday, March 25, 2004, 5:45:52 PM, you wrote:

AB PHP Version 4.0.4pl1

Wow, that's an old version of PHP! It could be the cause of this,
there's nothing in you phpinfo to give anything else away (i.e. it's
identical to mine).

-- 
Best regards,
 Richard Davey
 http://www.phpcommunity.org/wiki/296.html

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php