--- 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, "$message<br />"); > 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="message"><br /> > <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