0

I am currently having an issue with using a nonce as a security solution in PHP

i read this post about How to check if a request if coming from the same server or different server?

about using an hidden input form field to hash a random value and At the same time, store that random value into the session that correspond to the user. When the form is submitted, check that the hidden field has the same value as the one that's stored in session. (I think am having a problem with this)

Example

<?
$_SESSION['formhash'] = md5('any value to be hashed');
?>
<input type="hidden" name="hashed" id="hashed" value="<?php echo $_SESSION['formhash']; ?>" />

A user having an Mozilla Firebug and inspecting the element will still find out my hidden field and then copy it. And then create his/her own form then post it to my url and the Login will still be Bypassed.

Image showing example

enter image description here

Is there any more secure way to do this ? Any help will be appreciated thanks !

Community
  • 1
  • 1
Tosin Onikute
  • 3,883
  • 6
  • 38
  • 61
  • You do understand that a nonce is a *number used once*, right? *Random* and *generated per request*, right? Once you receive a form containing your nonce, you should remove it from the session and never use that value ever again. *That* is the part that makes it useful; if someone can predict what the nonce will be, it is useless. – cHao Apr 11 '14 at 04:54
  • What am saying is whether it is possible to prevent the user from manipulating the form data, because browser gives users the ability to view form hidden elements with Inspector ! – Tosin Onikute Apr 11 '14 at 05:10
  • So? Let them view it, copy it, manipulate the hell out of it. It doesn't matter -- they can't reuse the hash if you know what you say you know. And regardless of what they change or copy, they can't do anything too shady, because you're validating on the server side anyway. You *are* validating, *right?* – cHao Apr 11 '14 at 05:12
  • Yes i am validating at server side – Tosin Onikute Apr 11 '14 at 05:20
  • Well, if the hidden value is different for every request, and you're making sure the form data is valid, and you're encoding it properly for wherever you're storing or displaying it, it doesn't really matter what the user can see with their dev tools. They can still only do what your code lets them do. – cHao Apr 11 '14 at 05:26

1 Answers1

1

The bottom line is that you cannot prevent a user from manipulating the form data prior to submitting the form. What your solution does is confirms that the form data is coming from the user you sent it to.

Regardless of whether or not a user is "logged in", you will probably start a session each time a new visitor hits your site. This means you can store the hash value each time you send them a form and you should, in theory, be able to associate the hash value on the returned form data with the hash value in the session (just like your code is doing).

Armed with that knowledge, we can consider the following scenarios:

  1. The typical use case is that a user submits a form without modifying the data. Your approach will allow you to confirm that the form has been posted by that very user. Your validation code should confirm that the POST data is acceptable.

  2. If a user modifies the form data and submits it, your approach will allow you to confirm that the form has been posted by that user, but not that the form has been messed with. This is why you need to validate forms very, very carefully.

  3. If a user grabs a form that was actually sent to someone else and posts it - modified or not - your system will allow you to confirm that the form did not come from the user that it was originally sent to and you should reject it.

Scenario 3 is what is known as a CSRF attack and your solution is the standard defense against this attack.

PS As @cHao says, you should regenerate the hash for every form you generate.

JamesG
  • 4,288
  • 2
  • 31
  • 36
  • ok thanks for your explanation, but do you think there might be possible PHP solutions in the future that might solve this problem specifically. except that my validation code must confirm that the POST data is acceptable, Just as you have said – Tosin Onikute Apr 11 '14 at 05:18
  • No, there will never be a way to stop the client manipulating the form data. Think about it more like an API that you have implemented, written a spec for and given the spec to some other people to code against. Even though you really want them to follow the spec, if they make a mistake or want to be malicious they can try sending requests that don't conform to the API (fields that are too long, fields that are missing, fields that have bad data etc). Sending the form data to the browser is the equivalent of sending someone a copy of the API spec. You hope they follow it, but they might not. – JamesG Apr 11 '14 at 21:25