Problem
I am developing an application (in PHP) in which, I will show the user a report of some derived values based on previous entries he had done and the user will check for correctness - if correct, then the user can press Save button to submit it to database. Otherwise, the user should be able to edit previous entries, but he should not be able to change derived values in that report.
For that purpose, I have enclosed these values in a hidden input field, so a normal user can not alter these values, but if web developers could inspect the element in their browser and change these values.
Can we prevent these type of attack? If so, how?
My thoughts
I can make a string of all hidden fields, encrypt it and save in another hidden field - after postback I can cross-verify actual value and encrypted value.
Is this the correct way to achieve this? and how to do this
What do you think?
It's very hard to get a good idea of what you are trying to do but perhaps a solution could be to display a form with input fields disabled (http://www.w3schools.com/tags/att_input_disabled.asp) then have at the bottom of your page e.g. Is this information correct? .. Then 1 option to Save, and one option for No/Edit. Then do an if(isset($_POST['edit'])) { .. run form again but with input fields not disabled }
Only have your SQL update code in the 'edit' section of the code, and have a seperate SQL update code for the save section which just moves the values from wherever you are grabbing them from, to wherever they need to be.
Hope that helps.
If there are derived values that you need to fill out your form, but don't want to use hidden fields - I suggest using session variables that would contain those derived values as needed. Depending on how many of these forms there are, and how many users will be using them - the overhead is usually negligible with this number of fields (in the 30s)... if you discard them when not needed of course.
Related
I've just started recently to delve into the depths of html/php & co, so basically I'm a noob.
My question is simple: I'm using a php session to store a variable I'm using for an operation on the successive page. This variable is 'id' which is the primary key of my postgreSQL table. The user has a form on the web page in which it inserts the 'id' so as to select a particular row of the database to visualize and modify. Since the operations of visualization and modification are all in successive pages, I wanted the variable to remain memorized through the session (so that it's not required to post it again every time)
$_SESSION[id] = $_POST[id]
The problem arises when on a successive page I try to use a form to modify data on that particular row. I don't want the user to have to submit the 'id' again, so I use a select that involves $_SESSION[id]. But when the user submits the form, $_POST[id] is not specified in that form and its value goes to null. The result is that $_SESSION[id] is null and I cannot access the database using the query.
I found a way to solve the problem, but I find it extremely inelegant. I basically add a hidden section on the form that sends the id variable like this
<input type="hidden" name="id" value="$_SESSION[id]">
Is there a better way to do this?
I really hope my question makes sense to you, feel free to comment for additional info.
Thanks a lot :)
I've been reading PHP form handling tutorials, and they suggest using a hidden field in the form so PHP can use something like IF ($_POST['hidden_field'] == whatever to detect whether the form was submitted or only displayed.
But after getting XDebug working with Notepad++ and stepping through the code and observing the variables, it's not clear to me why we can't just go IF ($_POST['submit_button'] == 'Ok') and do away with the hidden field entirely.
After all, there doesn't seem to be a time when the hidden field is set without the other form fields being set too (even if they're empty). The first time through, when the form is being displayed and before it has been submitted, the $_POST variable already exists, but it is empty. I suppose we could also use IF (!empty($_POST)) to see if the form has been submitted?
Is there a special case I'm missing where the hidden field is necessary to detect form submission?
EDIT: Ok, the special case I was missing and that requires the hidden field appears to be this. http://www.vbforums.com/showthread.php?562749-PHP-Checking-if-a-form-has-been-submitted-the-correct-way It seems that if you hit Enter to submit the form, the $_POST variable will not include the value of the submit button. Chrome doesn't seem to behave that way but maybe other browsers do.
Is there a special case I'm missing where the hidden field is
necessary to detect form submission?
To detect the form submission you don't need a hidden field in the form but some times it's used as a spam protection. For example, if you put a hidden field in your form, like
<input type="text" name="humans" id="humans" class="humans" />
You may use a css class to hide the filed like
.humans { display: none; }
and when you check the form submission, you may also check if the field is empty or not, like
if(!empty($_POST['humans'])) {
// it's spam
}
else {
// it's human
}
Because, bots/spammers (using automated script) can submit the form and basically the script tries to fill up all the fields and doesn't know about the hidden field that you have put to catch it and this way you may determine whether it's submitted by a human or bot. You may read this article for more information and better understanding of spam blocking..
No, you have the right idea.
I wouldn't recommend doing this, however - sounds like whoever wrote the tutorial is a bit of a newbie. ;) If you're using POSTs for your forms already, I'd stick with the more traditional (and simpler) method of detecting whether the form was submitted or if someone is just viewing the page by means of the HTTP method ($_SERVER['REQUEST_METHOD'], as "GET" or "POST" in PHP).
Why implement a [hidden] field to check if the form is submitted when you must have other fields to check by if you have a form in the first place.
Other than checking if submitted, the hidden field is redundant, and so just pointless extra code.
If you have multiple forms on a page, name the submit button, if only one, just check if $_POST isset(), then go about validating data, etc etc
You can use !empty($_POST) instead, but I try to avoid this (depending on scenario) as I like to tell the user they did not enter anything, otherwise user clicks submit and it just hows them the blank form again.
Sure they would likely know they're messing around, but perhaps they thought they typed something, for numerous potential reasons.
Always good to keep users appraised, especially of any potential mistakes on their part.
There is no difference in using a hidden field just to check that the form has been submitted.
But let's say you want to dynamically post a value that there is no reason to show in the form.
For example you have an array $user that holds all the data of a user. The user submits the form, and you pass as a hidden field $user['id'] to work with their id after the submission.
Or you find their language through IP or whatever and pass it as a hidden field to show a message in their language.
Although I don't do this myself, I would say that it can be useful to undermine curl or other methods of accessing the site outside of a regular browser - of course the hidden field has to differ with every request.
Yes, there are multiple use of hidden field to validate a submit
as you mentioned, differentiating between form view and submission.
as #kingkero mentioned, a way to block form auto submissions by robots.
and in case of editing an existing record
a primary key is required to locate original record, and it should be hidden so user can't change it
you can save old data somewhere in server side before sending to browser and then send a reference key to that data as hidden field, later it can be used to compare old and new data to determine what has been changed.
in multi-user system, if more then one user select to edit and save a specific record at the same time then there is chance that they can overwrite each-other!! to prevent this situation a hidden field can be used to determine and notify user if selected record has been changed during form load and submit period.
I'm using Codeigniter for building a website. The website has an option called 'update record' which allows the user to update 50 different values. The update page has the old value along with an empty text box for the user to enter the new value. Updating the whole record even though the user has not actually updated anything makes no sense (website uses MySQL database). I've tried using hidden form field with the original value and tried to update only modified fields. Though it is working fine, the process looks so lengthy every time comparing the old value with the new one and updating only if there is a change.
Is there a better way to do this (with or without using codeigniter)? Just curious to know.
Thanks in advance.
I would parse the post array and remove any entries that don't have a value for updated (which would mean the input was submitted empty).
Then you could only update the modified records
I don't know how code igniter passes the post array into the controller after form submission but you could do something like
<?php
foreach ($postData as $key => $value) {
if (empty($value)) {
unset($postData[$key]);
}
}
The only place this would fall down is if you legitimately want to store an empty record as the updated value.
I use javascript to do filter only updated values
1 - I use hashes.js to calculate a sha1 when page loaded. store it in hidden or just a variable, or you can do sha in the server.
2 - I also do a snapshot of the form in array when page loaded. I put all my input in one class and use jQuery('forminputs').each to put them in array.
3 - when user click submit, first I do another snapshot of the form as No. 2 and compare the hash. if the hash diff, I use php.js get the updated value php.array_diff_assoc(newsnapshot, oldsnapshot). and post this to server.
Though these seems like a lot of computation, but in fact it is not slow at all in firefox or chrome(never try IE).
I have a PHP application form for medical health plans where the user fills in his details and selects some options from various controls, one of which is the plan type (private of family plan). Sometimes, although the user fills in his siblings/spouse details, they forget to also select the 'family' option and leave the drop down at it's default value which is the 'private' plan.
How can I make sure that if the user fills in his sibling's details, that the 'plan' dropdown will change to the proper option? I know this can be done easily with js but I'm not sure what event I should call it on, onFocus and onClick won't work because the user might simply click on the Sibling Name field but not enter a value, fill in something but later on clear it out etc.
I think that a script that counts the length of the 4 available siblings fields and if one of them is not empty, then change the 'plan' select value from 'private' to 'family'.
Any ideas would be great, thanks.
You've givin the answer partially yourself: you'll need a function that checks if the fields are not empty (or some other random condition). Lets call that function checkCondition()
Next you'll need a validation function that calls on it and changes the fields if appropriate, you can also combine these two functions but the code usually looks cleaner if you seperate them. E.g. ensureValidFieldPlan()
Then you can hook that function to run on the appropriate times. The simplest way to do it is in the forms onChange. A better way to do it would be to hook it to the appropriate form field, but for simplicity sake lets hook it to the form.
Your total code will look something like this:
function checkCondition(){
return form.field1.value.length != 0;
}
function ensureValidFieldPlan(){
if( form.plan.value != 'family' && checkCondition()){
form.plan.value = 'family'
}
}
form.onchange = function(){ form.onChange(); ensureValidFieldPlan(); };
Note that this does not guarantee that a browser client will transfer a valid form (e.g. it can be spoofed), you should always also perform server-side validation.
Depends on how you want to handle it, server side? Indeed, detect the
strlen($_POST['siblingname']) > 0
and then set your plan automatically to familly from the php code before processing something else.
If you want to do it on the client side. I suggest to use the popular JQuery library and intercept the value change event on the sibblingname field. Then, in the event handler, check the length of the sibbling name field value, if there is something, just set the plan to family.
Good luck
I've got a populated table which admins can edit and a submit button to apply all the changes made but I was wondering if I could narrow it down to only the ones they changed? I don't mind having an extra checkbox to specify whether it requires updating or not which the user can check but I don't know how to send ONLY those parts of the form to $_POST.
Thanks in advance.
The entire form will be posted by default.
To do what you want to do you can of course go the Javascript way.
Making users click on e.g. a checkbox for the records they have changed wouldn't be the preferred way IMO.
You could use JavaScript to note the changes, update a hidden field and post these instead.
You could also add the current values to the session and then check on submission which ones have changed by comparing the session values to the post values.