Re: [PHP] Securing Forms???
Chris Shiflett wrote: You might find these resources helpful: http://education.nyphp.org/phundamentals/PH_spoofed_submission.php http://shiflett.org/talks/oscon2004/php-security/36 Hope that helps. Just wanted to chime in to the list and to Chris. I've been mulling the example in the second link since last we talked about this, and I modified the example to make an even safer example (IMHO). The idea of using the plain token in the form, and using it to compare with the session wasn't sitting well with me for some reason (maybe bad karma in the air or something), so I borrowed an idea from a previous article you wrote on session hijacking, by utilising a private key. The goal, is so that one cannot really determine what the comparison token can be by looking at the hidden field value of token. Comments are welcome... --- ?php session_start(); $some_hidden_key = 'abcde...'; if (isset($_POST['message'])) { if ($_POST['token'] . $some_hidden_key === $_SESSION['token']) { $message = htmlentities($_POST['message']); $fp = fopen('./safer.txt', 'a'); fwrite($fp, $messagebr /); fclose($fp); } } $token = md5(uniqid(rand(), true)); $_SESSION['token'] = $token . $some_hidden_key; ? form method=post action=?php echo $_SERVER['PHP_SELF']; ? input type=hidden name=token value=?php echo $token; ? / input type=text name=messagebr / input type=submit /form ?php readfile('./safer.txt'); ? -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
On Fri, 13 Aug 2004 12:39:07 -0700 (PDT), in php.general [EMAIL PROTECTED] (Chris Shiflett) wrote: http://shiflett.org/talks/oscon2004/php-security/36 $token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. $token = md5(uniqid(rand() )); ought to be sufficient - and works with PHP4 :) -- - Peter Brodersen -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
Peter Brodersen wrote: http://shiflett.org/talks/oscon2004/php-security/36 $token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. How do you figure that? md5() only returns 0-9 and a-f characters. $token = md5(uniqid(rand() )); ought to be sufficient - and works with PHP4 :) Using entropy with uniqid() simply returns a more unique value to md5(), so what's the difference. -- ---John Holmes... Amazon Wishlist: www.amazon.com/o/registry/3BEXC84AB3A5E/ php|architect: The Magazine for PHP Professionals www.phparch.com -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
On Wed, 18 Aug 2004 17:59:34 -0700, in php.general [EMAIL PROTECTED] (John Holmes) wrote: $token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. How do you figure that? md5() only returns 0-9 and a-f characters. From the manual: http://php.net/md5 string md5 ( string str [, bool raw_output]) If the optional raw_output is set to TRUE, then the md5 digest is instead returned in raw binary format with a length of 16. raw_output is set to true, meaning that md5() will not just return a hexdump of the digest, but a raw binary format, which could contain quotes and other special characters. There's about 6% probability of md5 returning (at least) one double quote for a random input :) $token = md5(uniqid(rand() )); ought to be sufficient - and works with PHP4 :) Using entropy with uniqid() simply returns a more unique value to md5(), so what's the difference. Err... the only difference is that I removed the second argument, making md5() return a simple hex-encoded string. -- - Peter Brodersen -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
--- Peter Brodersen [EMAIL PROTECTED] wrote: http://shiflett.org/talks/oscon2004/php-security/36 $token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. That's incorrect. An MD5 is a hexadecimal number. Chris -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
On Wed, 18 Aug 2004 15:26:34 -0700 (PDT), in php.general [EMAIL PROTECTED] (Chris Shiflett) wrote: $token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. That's incorrect. An MD5 is a hexadecimal number. Ah, damn you, parenthesis :) I read it as: md5(uniqid(rand()), true); My bad - sorry! -- - Peter Brodersen -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
* Thus wrote Peter Brodersen: On Wed, 18 Aug 2004 17:59:34 -0700, in php.general [EMAIL PROTECTED] (John Holmes) wrote: $token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. How do you figure that? md5() only returns 0-9 and a-f characters. ... $token = md5(uniqid(rand() )); ought to be sufficient - and works with PHP4 :) Using entropy with uniqid() simply returns a more unique value to md5(), so what's the difference. Err... the only difference is that I removed the second argument, making md5() return a simple hex-encoded string. The second argument was to uniqid(). Curt -- First, let me assure you that this is not one of those shady pyramid schemes you've been hearing about. No, sir. Our model is the trapezoid! -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
$token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. How do you figure that? md5() only returns 0-9 and a-f characters. From the manual: http://php.net/md5 string md5 ( string str [, bool raw_output]) If the optional raw_output is set to TRUE, then the md5 digest is instead returned in raw binary format with a length of 16. The true is the second argument (more_entropy) for uniqid. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
--- Peter Brodersen [EMAIL PROTECTED] wrote: raw_output is set to true, meaning that md5() will not just return a hexdump of the digest, but a raw binary format, which could contain quotes and other special characters. I see your mistake now. That second argument is for the uniqid() function. Have another look and pay close attention to parentheses. :-) Chris = Chris Shiflett - http://shiflett.org/ PHP Security - O'Reilly Coming Fall 2004 HTTP Developer's Handbook - Sams http://httphandbook.org/ PHP Community Site http://phpcommunity.org/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
On Wed, 18 Aug 2004 15:57:26 -0700 (PDT), in php.general [EMAIL PROTECTED] (Chris Shiflett) wrote: I see your mistake now. That second argument is for the uniqid() function. Have another look and pay close attention to parentheses. :-) My arch enemy, Parenthesis, we meet again. And I can see that you have grown stronger since our last encounter! -- - Peter Brodersen -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
$token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. How do you figure that? md5() only returns 0-9 and a-f characters. From the manual: http://php.net/md5 string md5 ( string str [, bool raw_output]) If the optional raw_output is set to TRUE, then the md5 digest is instead returned in raw binary format with a length of 16. true is an argument to uniqid(), in that snippet: string uniqid ( [string prefix [, bool more_entropy]]) You would run the risk of messing up the form with (sound of pipe organ) *excessive entropy*. - michal migurski- contact info and pgp key: sf/cahttp://mike.teczno.com/contact.html -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
Peter Brodersen wrote: $token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. How do you figure that? md5() only returns 0-9 and a-f characters. From the manual: http://php.net/md5 string md5 ( string str [, bool raw_output]) If the optional raw_output is set to TRUE, then the md5 digest is instead returned in raw binary format with a length of 16. That true is the second parameter to uniqid(), not md5(). -- ---John Holmes... Amazon Wishlist: www.amazon.com/o/registry/3BEXC84AB3A5E/ php|architect: The Magazine for PHP Professionals www.phparch.com -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
--- Gerard Samuel [EMAIL PROTECTED] wrote: http://education.nyphp.org/phundamentals/PH_spoofed_submission.php http://shiflett.org/talks/oscon2004/php-security/36 Hope that helps. Just wanted to chime in to the list and to Chris. Hi. :-) I've been mulling the example in the second link since last we talked about this, and I modified the example to make an even safer example (IMHO). The idea of using the plain token in the form, and using it to compare with the session wasn't sitting well with me for some reason (maybe bad karma in the air or something), so I borrowed an idea from a previous article you wrote on session hijacking, by utilising a private key. The idea, although presented a bit differently, is the same. The goal, is so that one cannot really determine what the comparison token can be by looking at the hidden field value of token. Before I comment on your code, I think it's worth pointing out that the risk this method attempts to mitigate is a spoofing of the form. This can come in many forms, but here are two examples: 1. Bad guy uses a CSRF attack on good guy. Thus, good guy submits a form of the attacker's choosing (a forged HTTP request). This method complicates such an attack, because the attacker won't know the token. This is sometimes called a shared secret, because the token is known by the user and the server - third parties have a difficult time compromising this (SSL can mitigate the concern for man-in-the-middle attacks). 2. Bad guy uses the application and wants to submit the form without using the form you provide. This method complicates this, because without at least receiving the form you provide once, there is no way to collect the token. Your data filtering on the server side should take care of the rest. Comments are welcome... --- ?php session_start(); $some_hidden_key = 'abcde...'; if (isset($_POST['message'])) { if ($_POST['token'] . $some_hidden_key === $_SESSION['token']) { $message = htmlentities($_POST['message']); $fp = fopen('./safer.txt', 'a'); fwrite($fp, $messagebr /); fclose($fp); } } $token = md5(uniqid(rand(), true)); $_SESSION['token'] = $token . $some_hidden_key; ? form method=post action=?php echo $_SERVER['PHP_SELF']; ? input type=hidden name=token value=?php echo $token; ? / input type=text name=messagebr / input type=submit /form ?php readfile('./safer.txt'); ? This doesn't provide any benefit that I can see, but I'm ready to admit that I might be missing something. If the token is captured, the conditional statement can still be bypassed, because the value of $some_hidden_key isn't necessary for this at all. Anyway, I'm a bit rushed, and I'll be happy to have a better look later if this doesn't make sense, or if it seems like I'm wrong. :-) Chris = Chris Shiflett - http://shiflett.org/ PHP Security - O'Reilly Coming Fall 2004 HTTP Developer's Handbook - Sams http://httphandbook.org/ PHP Community Site http://phpcommunity.org/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
Peter Brodersen wrote: On Wed, 18 Aug 2004 17:59:34 -0700, in php.general [EMAIL PROTECTED] (John Holmes) wrote: $token = md5(uniqid(rand(), true)); .. is a pretty bad idea, since the output could include quotes, newlines, low-ascii-characters, thereby messing up the form. How do you figure that? md5() only returns 0-9 and a-f characters. From the manual: http://php.net/md5 string md5 ( string str [, bool raw_output]) If the optional raw_output is set to TRUE, then the md5 digest is instead returned in raw binary format with a length of 16. Double check the example that I originally provided. -- md5( uniqid(rand(), true) ) -- Im not using the raw_output option of md5() md5( uniqid(rand(), true) ) -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
Chris Shiflett wrote: This doesn't provide any benefit that I can see, but I'm ready to admit that I might be missing something. If the token is captured, the conditional statement can still be bypassed, because the value of $some_hidden_key isn't necessary for this at all. Anyway, I'm a bit rushed, and I'll be happy to have a better look later if this doesn't make sense, or if it seems like I'm wrong. :-) The idea was just that, an idea. I was trying to play out mechanics/scenarios in my head, before blindingly changing my code to suit this secure method. But thats for the conversation... -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
On Fri, 13 Aug 2004 18:57:24 -0400, Gerard Samuel [EMAIL PROTECTED] wrote: Chris Shiflett wrote: You might find these resources helpful: http://education.nyphp.org/phundamentals/PH_spoofed_submission.php http://shiflett.org/talks/oscon2004/php-security/36 Hope that helps. Thanks. These are doable.. With curl I can automate pretty much any web site, you can't tell the difference between it and somebody using a browser. You are better off worrying about sanatizing the incoming data then securing the form. Let your session handling and login stuff take care of that. -- Use Linux. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
Nobody Special wrote: With curl I can automate pretty much any web site, you can't tell the difference between it and somebody using a browser. You are better off worrying about sanatizing the incoming data then securing the form. Let your session handling and login stuff take care of that. This isn't about sanitizing data. This is about making a user unknowingly make a request to another site. Yes, you can automate things with cURL, but the requests are coming from your server, not the user you're trying to abuse. You could simulate their cookies, but you'd have to get them first, which isn't always easy or possible. With a CSRF attack, you have the user make the request and send their cookies, data, whatever, without them even knowing it. -- ---John Holmes... Amazon Wishlist: www.amazon.com/o/registry/3BEXC84AB3A5E/ php|architect: The Magazine for PHP Professionals www.phparch.com -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Securing Forms???
[snip] I've read (at least on 2 occasions) that one can secure their forms, to ensure that the form came from the site, and not via a script kiddie. Not the method where one puts a graphic of random text to copy to the form, but via a hidden field. It has to do with having a hidden field of data, that must match some data, when the form is posted. I've been mulling over this for some time to figure out how its possible, (as I haven't seen a live example of it). Could anyone point me to an example to how this can be done, (if its even possible)??? Thanks for your input... [/snip] Make an MD5 hash of your form's text when you have it complete. Test for that when submitted. If it matches, it is yours. People who want to hack your form will look at the source, so they'll see any hiddens you have. But one small change and the hash will not match. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
On Friday 13 August 2004 02:57 pm, Gerard Samuel wrote: I've read (at least on 2 occasions) that one can secure their forms, to ensure that the form came from the site, and not via a script kiddie. Not the method where one puts a graphic of random text to copy to the form, but via a hidden field. It has to do with having a hidden field of data, that must match some data, when the form is posted. I've been mulling over this for some time to figure out how its possible, (as I haven't seen a live example of it). Could anyone point me to an example to how this can be done, (if its even possible)??? Thanks for your input... I think you're looking for something like this, but be warned things like HTTP_REFERER are/can be set by the client so you can't really trust this too much. if ($_SERVER['HTTP_REFERER'] != 'http://domain.com/I/AM/EXPECTING/script.php') { echo (Dang Script Kiddie Go Away!); exit; } Probably better is to include, like you said, a hidden variable on the page that would be very hard to guess in the form before presenting it to the user and also save it in a database or somewhere. Then when the user submits the form check your database for the existence of the super hard to guess value. If it exists in the DB, delete it and let the user go about her business. If it doesn't then: { echo (Dang Script Kiddie Go Away!); exit; } James -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Securing Forms???
--- Jay Blanchard [EMAIL PROTECTED] wrote: [snip] I've read (at least on 2 occasions) that one can secure their forms, to ensure that the form came from the site, and not via a script kiddie. Not the method where one puts a graphic of random text to copy to the form, but via a hidden field. It has to do with having a hidden field of data, that must match some data, when the form is posted. (Sorry, I missed the original email.) You might find these resources helpful: http://education.nyphp.org/phundamentals/PH_spoofed_submission.php http://shiflett.org/talks/oscon2004/php-security/36 Hope that helps. Chris = Chris Shiflett - http://shiflett.org/ PHP Security - O'Reilly Coming Fall 2004 HTTP Developer's Handbook - Sams http://httphandbook.org/ PHP Community Site http://phpcommunity.org/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
* Thus wrote Gerard Samuel: I've read (at least on 2 occasions) that one can secure their forms, to ensure that the form came from the site, and not via a script kiddie. Not the method where one puts a graphic of random text to copy to the form, but via a hidden field. It has to do with having a hidden field of data, that must match some data, when the form is posted. I've been mulling over this for some time to figure out how its possible, (as I haven't seen a live example of it). Could anyone point me to an example to how this can be done, (if its even possible)??? Thanks for your input... http://shiflett.org/php-security.pdf Curt -- First, let me assure you that this is not one of those shady pyramid schemes you've been hearing about. No, sir. Our model is the trapezoid! -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
On Fri, 13 Aug 2004 15:36:34 -0400, James E Hicks III [EMAIL PROTECTED] wrote: On Friday 13 August 2004 02:57 pm, Gerard Samuel wrote: I've read (at least on 2 occasions) that one can secure their forms, to ensure that the form came from the site, and not via a script kiddie. Not the method where one puts a graphic of random text to copy to the form, but via a hidden field. It has to do with having a hidden field of data, that must match some data, when the form is posted. I've been mulling over this for some time to figure out how its possible, (as I haven't seen a live example of it). Could anyone point me to an example to how this can be done, (if its even possible)??? Thanks for your input... I think you're looking for something like this, but be warned things like HTTP_REFERER are/can be set by the client so you can't really trust this too much. if ($_SERVER['HTTP_REFERER'] != 'http://domain.com/I/AM/EXPECTING/script.php') { echo (Dang Script Kiddie Go Away!); exit; } Probably better is to include, like you said, a hidden variable on the page that would be very hard to guess in the form before presenting it to the user and also save it in a database or somewhere. Then when the user submits the form check your database for the existence of the super hard to guess value. If it exists in the DB, delete it and let the user go about her business. If it doesn't then: { echo (Dang Script Kiddie Go Away!); exit; } Of course, you can then use somehting like HTTP_Client to both get the REFERER right and parse the HTML to get the hidden field you need. There is no sure-fire way to check for non-humans. You can use CAPTCHA, but there are programs to break those, too. ;-) CAPTCHAs are actually your best bet. -- DB_DataObject_FormBuilder - The database at your fingertips http://pear.php.net/package/DB_DataObject_FormBuilder paperCrane --Justin Patrin-- -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Securing Forms???
Chris Shiflett wrote: You might find these resources helpful: http://education.nyphp.org/phundamentals/PH_spoofed_submission.php http://shiflett.org/talks/oscon2004/php-security/36 Hope that helps. Thanks. These are doable.. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php