php-general Digest 28 Jul 2011 09:13:21 -0000 Issue 7419
Topics (messages 314219 through 314225):
Re: Membership site
314219 by: Ashley Sheridan
314222 by: Negin Nickparsa
314224 by: Ashley Sheridan
314225 by: John Black
PayPal IPN
314220 by: Jason Pruim
314221 by: Daniel Brown
314223 by: John Black
Administrivia:
To subscribe to the digest, e-mail:
php-general-digest-subscr...@lists.php.net
To unsubscribe from the digest, e-mail:
php-general-digest-unsubscr...@lists.php.net
To post to the list, e-mail:
php-gene...@lists.php.net
----------------------------------------------------------------------
--- Begin Message ---
On Wed, 2011-07-27 at 14:01 -0700, wil prim wrote:
> Hello, I am just starting out with PHP and I have just created a database
> named "Members" with a table named "Persons". There are 5 fields
> (id,firstname, lastname, username, password) . The form I created is a sign
> up form and the values entered into the form are inserted into the table
> "Persons", now my question is how do I create a secure log in system with
> this new database? Thanks in advance! :)
>
Well, first, as a measure of security, make sure that you don't store
the plain text password in the DB. Something like an md5($password .
$email . $name) offers a rudimentary protection. For something a little
meatier, try sha1(). Storing it this way means that even if someone
gained access to your DB, they don't actually have the passwords, as
people often reuse passwords on different sites.
As to the login, you would accept the username and password combo, and
then hash or encrypt the password with the salt again, and compare with
the entry in the DB. It's typical to have a counter of incorrect logins
as well. More than 3 in a row causes the login for that username to lock
for a specific period of time. To achieve this, you would need to add a
couple of fields to your Persons table, `attempts`(tinyint) &
`lock_time`(datetime).
When you attempt to log someone in with the username and password
(encrypted, hashed, whatever) you also check to see if the lock_time is
not some time in the future. If it is, then you don't allow them access.
If the password was wrong, then increment the attempts field by 1. If
this field gets incremented to a specific value (say 3 for example) then
you set the lock_time field to some date in the future, the wait period.
When a user logs in successfully, set the attempts counter to 0 again so
it's ready for the next login attempt to the account. This just ensures
that people aren't accidentally locked out indefinitely!
This is all just a rough sketch out of how I'd go about it, but it
should be enough logic for you to put some code together. It's no more
complex than a couple of queries and a few if statements. It may help
you to flowchart the whole thing out to get the logic clear in your
mind.
--
Thanks,
Ash
http://www.ashleysheridan.co.uk
--- End Message ---
--- Begin Message ---
http://www.php.net/manual/en/security.database.sql-injection.php
http://www.php.net/manual/en/security.database.storage.php
--- End Message ---
--- Begin Message ---
wil prim <wilp...@me.com> wrote:
>Ok so I have the md5() taken care of and now i have also attempted to
>create a login form plus a check login form that will try and match the
>hashed value of the input with a field in the data base and if
>successful it will echo 'You are now logged in' or else it will echo
>'couldnt connect'. However when I try to log in with my newly created
>username and password it echos 'couldnt connect'. Here is the code for
>the form:
>
><form method="post" action="check_login.php">
> <span style="font-size: 14pt;">
> Username: <input type="text" name="logginname" /><br/><br/>
> Password: <input type="password" name="loginpassword" /><br/><br/>
> <input type="submit" value="login" />
></form>
>
>AND HERE IS THE check_login.php:
>
><?php
>
>include_once "connect_mysql.php";
>
>$result=mysql_query("SELECT * FROM Members");
>$row=mysql_fetch_array($result);
>$loginusername=$_POST['logginname'];
>$loginpass=$_POST['logginpassword'];
>$hash_loggin_username=md5($loginusername);
>$hash_loggin_password=md5($loginpass);
>if ($hash_loggin_username==$row['username'] &&
>$hash_loggin_password==$row['password'])
>{
> echo 'You are now logged in!';
>}
>else
> {
> echo 'couldnt connect';
> }
>?>
>
>In this code Members is the table and Persons is the database.
>
>
>
>
>
>On Jul 27, 2011, at 02:28 PM, wil prim <wilp...@me.com> wrote:
>
>> Thanks for that! I'll try and put some code together and I'll reply
>if I need some more help. ;)
>>
>> Sent from my iPhone
>>
>> On Jul 27, 2011, at 2:18 PM, Ashley Sheridan
><a...@ashleysheridan.co.uk> wrote:
>>
>> > On Wed, 2011-07-27 at 14:01 -0700, wil prim wrote:
>> >
>> >> Hello, I am just starting out with PHP and I have just created a
>database named "Members" with a table named "Persons". There are 5
>fields (id,firstname, lastname, username, password) . The form I
>created is a sign up form and the values entered into the form are
>inserted into the table "Persons", now my question is how do I create a
>secure log in system with this new database? Thanks in advance! :)
>> >>
>> >
>> >
>> > Well, first, as a measure of security, make sure that you don't
>store
>> > the plain text password in the DB. Something like an md5($password
>.
>> > $email . $name) offers a rudimentary protection. For something a
>little
>> > meatier, try sha1(). Storing it this way means that even if someone
>> > gained access to your DB, they don't actually have the passwords,
>as
>> > people often reuse passwords on different sites.
>> >
>> > As to the login, you would accept the username and password combo,
>and
>> > then hash or encrypt the password with the salt again, and compare
>with
>> > the entry in the DB. It's typical to have a counter of incorrect
>logins
>> > as well. More than 3 in a row causes the login for that username to
>lock
>> > for a specific period of time. To achieve this, you would need to
>add a
>> > couple of fields to your Persons table, `attempts`(tinyint) &
>> > `lock_time`(datetime).
>> >
>> > When you attempt to log someone in with the username and password
>> > (encrypted, hashed, whatever) you also check to see if the
>lock_time is
>> > not some time in the future. If it is, then you don't allow them
>access.
>> > If the password was wrong, then increment the attempts field by 1.
>If
>> > this field gets incremented to a specific value (say 3 for example)
>then
>> > you set the lock_time field to some date in the future, the wait
>period.
>> >
>> > When a user logs in successfully, set the attempts counter to 0
>again so
>> > it's ready for the next login attempt to the account. This just
>ensures
>> > that people aren't accidentally locked out indefinitely!
>> >
>> > This is all just a rough sketch out of how I'd go about it, but it
>> > should be enough logic for you to put some code together. It's no
>more
>> > complex than a couple of queries and a few if statements. It may
>help
>> > you to flowchart the whole thing out to get the logic clear in your
>> > mind.
>> >
>> > --
>> > Thanks,
>> > Ash
>> > http://www.ashleysheridan.co.uk
>> >
>> >
>
>On Jul 27, 2011, at 02:18 PM, Ashley Sheridan
><a...@ashleysheridan.co.uk> wrote:
>
>> On Wed, 2011-07-27 at 14:01 -0700, wil prim wrote:
>>
>> > Hello, I am just starting out with PHP and I have just created a
>database named "Members" with a table named "Persons". There are 5
>fields (id,firstname, lastname, username, password) . The form I
>created is a sign up form and the values entered into the form are
>inserted into the table "Persons", now my question is how do I create a
>secure log in system with this new database? Thanks in advance! :)
>> >
>>
>>
>> Well, first, as a measure of security, make sure that you don't store
>> the plain text password in the DB. Something like an md5($password .
>> $email . $name) offers a rudimentary protection. For something a
>little
>> meatier, try sha1(). Storing it this way means that even if someone
>> gained access to your DB, they don't actually have the passwords, as
>> people often reuse passwords on different sites.
>>
>> As to the login, you would accept the username and password combo,
>and
>> then hash or encrypt the password with the salt again, and compare
>with
>> the entry in the DB. It's typical to have a counter of incorrect
>logins
>> as well. More than 3 in a row causes the login for that username to
>lock
>> for a specific period of time. To achieve this, you would need to add
>a
>> couple of fields to your Persons table, `attempts`(tinyint) &
>> `lock_time`(datetime).
>>
>> When you attempt to log someone in with the username and password
>> (encrypted, hashed, whatever) you also check to see if the lock_time
>is
>> not some time in the future. If it is, then you don't allow them
>access.
>> If the password was wrong, then increment the attempts field by 1. If
>> this field gets incremented to a specific value (say 3 for example)
>then
>> you set the lock_time field to some date in the future, the wait
>period.
>>
>> When a user logs in successfully, set the attempts counter to 0 again
>so
>> it's ready for the next login attempt to the account. This just
>ensures
>> that people aren't accidentally locked out indefinitely!
>>
>> This is all just a rough sketch out of how I'd go about it, but it
>> should be enough logic for you to put some code together. It's no
>more
>> complex than a couple of queries and a few if statements. It may help
>> you to flowchart the whole thing out to get the logic clear in your
>> mind.
>>
>> --
>> Thanks,
>> Ash
>> http://www.ashleysheridan.co.uk
>>
First, please reply to the list too and not just me.
Why are you retrieving a list of every user in your db? Use a where clause in
sql, its much easier and faster.
You don't need to hash your usernanmes, just passwords. Also, echo out the full
query. What does it look like?
Finally, you're creating a query object of all the data from your query, but
then you're not looping through the rows, yet you're using a variable called
$row which has never been defined. If you turn on all errors and warnings you
would see this.
Thanks,
Ash
http://www.ashleysheridan.co.uk
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.
--- End Message ---
--- Begin Message ---
I would like to add some info about storing the password hash in the
database.
I recently tested how quickly one can brute force a simple md5('foo')
hash with a modern GPU. The results have been truly eye opening....
I have been able to break hundreds of hashes with my ATI 6870 in a
couple of days. Even with passwords in the 8 char length range ... and
even salted ones.
The problem is that md5 is optimized for speed. Which is nice if you
want to hash a file but it offers an attacker the option to brute force
your password.
The solution is to hash multiple times and if possible using a different
hashing algorithm.
http://php.net/crypt can help you here.
I wrote a new password class for my own projects which will use crypt()
with sha512, sha256, blowfish if available or fall back to a 3000 round
md5().
This approach makes it impractical to bruteforce the hash because every
single test will have to run md5() 3000 times before it can validate a
single hash.
This also adds a delay to the login process but the hash is only checked
once....
The code is released under the BSD license so you may use it in a
commercial application as well. The zip contains the class file and two
sample pages demonstrating how to use the class.
Here is a download link, let me know if you like it or have any questions.
http://www.2shared.com/file/kocAJ2HO/class_password.html
md5: 4ee41496a9d1bc147e5025699e2b764e class_password.zip
--
John
--- End Message ---
--- Begin Message ---
Hey everyone,
So I know this is related pretty strictly to paypal... But I also know that you
all most likely use it :)
So with that said... Has anyone successfully setup the IPN with paypal? I'm
trying to figure out to get it up and working and can't seem to wrap my head
around it... But then again, I've been at it for a few hours so I'm hoping in
the morning it gets more clear!
Here is the test code that I am working with:
<?PHP
error_reporting(E_ALL ^ E_NOTICE);
$email = $_GET['ipn_email'];
$header = "";
$emailtext = "testing 123";
// Read the post from PayPal and add 'cmd'
$req = 'cmd=_notify-validate';
if(function_exists('get_magic_quotes_gpc'))
{
$get_magic_quotes_exits = true;
}
foreach ($_POST as $key => $value)
// Handle escape characters, which depends on setting of magic quotes
{
if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1){
$value = urlencode(stripslashes($value));
} else {
$value = urlencode($value);
}
$req .= "&$key=$value";
}
// Post back to PayPal to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr,
30);//Test
//$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);// Live
// Process validation from PayPal
// TODO: This sample does not test the HTTP response code. All
// HTTP response codes must be handles or you should use an HTTP
// library, such as cUrl
if (!$fp) { // HTTP ERROR
} else {
// NO HTTP ERROR
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// TODO:
// Check the payment_status is Completed
// Check that txn_id has not been previously processed
// Check that receiver_email is your Primary PayPal email
// Check that payment_amount/payment_currency are correct
// Process payment
// If 'VERIFIED', send an email of IPN variables and values to the
// specified email address
foreach ($_POST as $key => $value){
$emailtext .= $key . " = " .$value ."\n\n";
}
mail("pru...@gmail.com", "Live-INVALID IPN", $emailtext . "\n\n" . $req);
//removed for testing
//mail($email, "Live-VERIFIED IPN", $emailtext . "\n\n" . $req);
} else if (strcmp ($res, "INVALID") == 0) {
// If 'INVALID', send an email. TODO: Log for manual investigation.
foreach ($_POST as $key => $value){
$emailtext .= $key . " = " .$value ."\n\n";
}
mail("pru...@gmail.com", "Live-INVALID IPN", $emailtext . "\n\n" . $req);
//Removed for testing
//mail($email, "Live-INVALID IPN", $emailtext . "\n\n" . $req);
}
}
}
fclose ($fp);
?>
Thanks everyone! Hoping to find a easy fix to it!
Jason Pruim
pru...@gmail.com
--- End Message ---
--- Begin Message ---
On Wed, Jul 27, 2011 at 21:58, Jason Pruim <pru...@gmail.com> wrote:
> Hey everyone,
>
> So I know this is related pretty strictly to paypal... But I also know that
> you all most likely use it :)
Remind me tomorrow. There's a chance I may have some old IPN code
lying around, and definitely have Website Payments Pro code that I
still use daily.
That aside, PayPal has development community forums for
PayPal-specific development: http://paypaldev.org/ .
Give it a shot. If it doesn't work, I'll see what code I still
have, but you'll totally owe me a 50-yardline shot from the Swamp.
--
</Daniel P. Brown>
Network Infrastructure Manager
http://www.php.net/
--- End Message ---
--- Begin Message ---
On 28.07.2011 03:58, Jason Pruim wrote:
Hey everyone,
So I know this is related pretty strictly to paypal... But I also know that you
all most likely use it :)
So with that said... Has anyone successfully setup the IPN with paypal? I'm
trying to figure out to get it up and working...
Hi Jason,
I might be able to help you with that. I don't have IPN integrated into
my site yet but I have a script running which is inserting the
transaction values into my db. It also sends out e-mails since I am
testing how my existing subscriptions are handled so I don't run into
any surprises when I turn on automation.
You need to import the .sql into your mysql db and edit the settings at
the top of the ipn file. Then rename the ipn file to something nobody
should be able to guess and tell PayPal about it ... let me know if you
run into trouble...
http://www.sendspace.com/file/77iofs
md5: 09f3f92050264c370ada7944555373ce PayPal IPN.zip
Good luck
--
John
--- End Message ---