I'm trying to write an app that basically is a frontend for editing database records. I have heard that a way to ensure the right row in the DB is being updated is to include a hidden form field on the update form with the row unique ID in it, and use this to add a conditional to the backend update statement.
However, this seems insecure. Anybody could edit the HTML on the page pre-submit and change the record being updated, no? What is the proper way to pass the unique ID of the row the user is editing along with their edits? I would imagine this may be done with cookies/session tracking, but couldn't this be edited client side prior to submitting as well?
Thanks!
If a client is allowed to modify the record in question anyway, it doesn't matter whether he does so by modifying the id in a hidden field or by going to the correct page and submitting the form from there.
When any client submits any form, the server needs to a) make sure the client has the right to modify the record he attempts to modify and b) validate that the submitted data is allowable for the record. Then all your business rules are being protected and taken care of, whether the user uses the proper forms or not.
You can also save a hash of all hidden fields in the session server-side and check that on submission to catch hidden field-manipulation attempts, if that's still in your interest.
You may create a field with default value TIMESTAMP.
Also you may pass this data from one page to another using php sessions
More details here
Hope this helps.. :)
When you load the form page, store the id in the session however you want to.
When they submit, on the post page, grab the id from the session.
The insecure part is, how are you letting people decide which id they want to edit? Where is the input for that?
Related
I'm trying to figure out the best practice, as well as safest, way to store a variable with javascript for a web app I'm developing.
I have pages that are generated using php, $_GET and mod_rewrite. They are generated from the id that's given through the url. For example: http://example.com/1125/ (because of mod_rewrite what's actually happening is: http://example.com?id=1125). The php takes $_GET['id'] and retrieves information from the database in accordance the id given, etc... you get the gist.
The problem I'm having is, I have a form on that page where a user can post a question, which is sent via ajax. And I don't know the best way to store the page's id ($_GET['id']).
Right now, I have the id stored in a hidden input within the form (for example: " />). And when the form is submitted to the server and php takes a look a $_POST, it contains ["id"] => 1125. That's how I'm sending the page's id when a question is submitted via the form in the page.
The reason I think that's not secure is, anyone can edit the html (for example through Chrome's inspect element) and change the hidden input's (id) value to any other id.
So my question is, what's the safest way I can store that id with javascript, so when that question form is submitted, It can safely send the correct id to the server? Or any other suggestions thought out with best practice methods?
You only just need to validate the id in the php page that receives the ajax, if the id is valid and the user has permission to use it, then it's ok and it doesn't matter if he changed it through chrome or whatever, but you need to validate because if he changed it for the id that belongs to other user then you have to detect that and error out in that case.
This is just a matter of validate your input according to the priveleges in your application.
This is inside a PHP website form.
An example is like:
First page:
-Username:
-Password
Second page:
-Email
-[Checkbox]
Thirdpage:
-Contact Details
-Address
Fourth page:
Review all of the above forms in hard copy but with a back and forward command so that the user does not loose any information when switching between these pages.
Please post.
You could use cookies and do your own sessions with MySQL too. I like doing it like that because the data is easier to access if necessary.
Or you can pass the previous variables to the next page though hidden form elements.. but that can get messy.
You Have to use session. I like Zend_Session.
If you want users to be able to come back later and complete the form (assuming you have some kind of login system, or a way to recognize users), you could still save the data into a database. Make another table, temp_submissions. Keep data in it until the user completes the form and commits the data they send. Once committed, clear the data out of the temp_submissions folder and insert it into the "permanent" table. It may not be practical in this case, or total overkill, but it's an alternative to sessions and cookies.
Further to my previous question, here's what I decided to implement; it may not be pure P-R-G, but it seems ok. Care to comment?
The form.php has an action; let's call it validate.php.
validate.php is never seen by the user; if validates all $_GET and, if valid writes it to database and generates the HTML of a confirmation page / if not valid, it generates the HTML of an error page explaining what is wrong.
Whichever HTML is generated get stored in a $_SESSION variable and then validate.php does a header('Location: <as appropriate>);
Finally a page called submitted.php of invalid_input.php (in case the user reads the URL) consists only of echo $_SESSION['form_html'];
That seems to me like is proff against both page reload and back button problems.
Or did I goof by trying to reinvent the wheel?
Firstly, you're better off storing the form data, which means you can perform the validation again. It will also be less html. The problem with the method you're employing now is that it doesn't protect against multiple tabs, since $_SESSION is universal to a browser session.
One way I've used to prevent against duplicate submission (without PRG) is to generate a unique id for every page load (where a form is involved). When I generate that unique id, I add it to a $_SESSION['form_unique_ids'] array, and I include it as a hidden field in every form I generate. Then before I take action on a form submission, I check to see if that unique id is in the session. If it is, this is the first time that form has been submitted, and I remove it from the session. That way if I try to resubmit that page, I will know because that id is not in the session not to process the results.
This could be extended so that instead of storing a single id, you use the id as the key in the array, and let the value be the result of the transaction. Then:
If there are errors, you store the $_POST data as well. Then, redirect to original_form.php?id=unique_id and display the validation results. You can either store them or recalculate them there.
If there is success, store the success message and redirect to success_page.php?id=unique_id. Display the success message prominently there. If you like, you can remove it from the page.
You have the option of removing the session data when you display it, but that would mean if they refreshed the edit page they'd lose the validation messages and saved form data. I'd rather find a way to get rid of data that is old enough that they're not likely to need it anymore.
Anyway, some of those ideas might be useful. Then again, maybe it's way too much effort for the problem. Your call :)
As long as you use a php redirect at the end of your validate you cannot reload or back button into the validate.php
I just had this thought, I don't know if I am slow though.
Usually, I store the id of the item I am editing in a hidden field. Then in backend (I am using PHP/Zend Framework btw), I get it to determine which item gets edited. But then I thought, in something more secure, eg. edit profile, the user can somehow edit a hidden field right? Then he can edit someone else's profile. I know for edit profile, I can get the id form the session variable, but what if i got something that requires me to store the id somewhere?
I got ACL (Zend_Acl) I do this. Basically grab the id from the request params
$id = $req->getParam('id');
then check if the logged in user is allowed to edit the item. But the thing is I wonder if the url is something like /users/edit/1 where 1 is the id. But somehow, the hidden field is changed to 2, what will the request param be?
How would you deal with this?
You must store some kind of id at the client-otherwise how would you know which item to edit?
This does not free you from the mandatory check on the server that the current user has privileges to edit/see the edited item.
Other then that, why would you care how he got to edit the item (whether by lawful use of the web tool, or by editing the hidden/whatever field).
Storing ID in hidden value isn't quite safe. Generally, we store ID in session variable.
as ppshein said, storing sensitive ids in a hidden var is NOT safe. Would you store a password in a hidden var? Its really easy for even a novice hacker to get that data.
You need to make sure that all access control is enforced by the server.
in your case, you need to make sure that the user who is logged in (the one on the session) is the owner of the profile being edited. Or that the user who is making the edits has permissions to edit that profile (e.g. is an admin)
It should not be based on anything submitted by the user.
You should always check user permissions on server side.
An attacker can prepare any request to your server.
Agree with all the points above but if you really do need to store something clientside for whatever reason, you can always encrypt the data and decrypt when you need to use it but again, using sessions would be the best way to deal with it as they are not accessible client side.
I'm currently developing a page where the user fills out a form, and when submitted they are taken to the next page. When on the next page, I want to have it so that if the user went back to the previous page using the back button, or hit refresh, the submission will not be saved into the DB.
Now I recall reading somewhere that if you had a way to make each submission unique, this issue is averted, but after screwing around for hours on end, for the life of me I cannot recall how this could be done (using PHP), so long story short has anyone ran into this, and if so, what was your solution?
Use the Post/Redirect/Get pattern to avoid this problem. See also Redirect After Post.
Another way is to generate an identifier using uniqid and include it in the form as a hidden input. On submission, store that identifier in a database column marked with a UNIQUE index. This will cause subsequent submissions to throw a SQL error, which your application can handle gracefully.
You can add any confirmation on the second page.
By adding any confirmation box or any button....
by which you can confirm that whether user want to save it or not....
and if you don't want any confirmation...then you can delete the last record....by using managing session...but it is not good practice to fire the query very soon and delete in that kind..
so best way will be by adding any confirmation msg....