I have a form:
<input type="text" value="3X732" readonly/>
Well, the user can use a program to edit the input value and then, break the system.
How can I prevent this? I can use anything, except scripts.
Ow an the value is dynamic, so I can't do something like $code = "3X732";
You should use $_SESSION to pass important data instead of html, never trust the user.
Encrypt the value and save the encrypted value in a hidden field in the form.
When the form is submitted run the same algorithm on the value of the text field and compare it to the encrypted value. They should match otherwise it has been fiddled with...
Related
I have a form that contains html entities in an input field, something like:
<input type="hidden" name="foo" value="<?php htmlspecialchars($foo) ?>" />
If $foo takes in the value of something like "<b>foo</b>", it seems that when the form is posted to the PHP script, the value of $_POST['foo'] is already decoded...so does that mean I don't need to use htmlspecialchars_decode to convert $_POST['foo'] back to its original form $foo?
Thanks for any inputs on this issue.
When it comes to user input, code very defensively. Never make any assumptions. While the initial state may be set by the server, there's nothing stopping someone from manipulating the value of your hidden input to a malicious value. At that point it's on you to handle that value responsibly, so make sure you cover any case that is possible.
Okay so my title might be a little confusing, but let me explain my situation:
I have a pretty big form with lots of fields, some which are required, some which are not. I do validation with JS, but then I'm also doing validation on the server side with PHP.
One of the things I'm asking the user for is a "Header Name". Now, header name has the name attribute of "header1". The user has the option of adding more header fields on the form. So if they click a button it adds another "Header Name X" with name attribute "headerx".
Got it? Now, the problem is, in general these header fields are not required, but I do have the condition that they MUST supply at least one Header field. So they could supply 100, they could supply 2, they might supply 1, but if they don't supply any then validation should fail.
I can't think of a good way of checking for this in PHP though. I know your fist thought is just check if $_POST contains anything. Won't work though because they are multiple other fields in this form that are required that have nothing to do with these Headers. So I can't just simply check to see if $_POST contains something because it always will.
Is there a way I can like combine isset() with a regular expression? Like isset($_POST['header{\d+}']. Which would be saying like header with atleast one digit following it.
Thanks for the help!
EDIT: Oh and if this wasn't hard enough already, the amount of Header Fields is limitless. So I can't just loop through all the possible "headerx" because that would obviously be an infinite loop.
You could have field names with []:
<input type="text" name="foo[]" value="x" />
<input type="text" name="foo[]" value="y" />
Then $_POST would be like:
array('foo' => array('x', 'y'));
You could even have associative arrays:
<input type="text" name="foo[bar][first]" value="x" />
<input type="text" name="foo[bar][second]" value="y" />
Would look like:
array('foo' => array('bar' => array('first' => 'x', 'second' => 'y')))
You can loop through the elements like this:
$i = 1;
while($row = $_POST['header' . $i++]){
//do stuff
}
this will keep going until there are no more sequential elements.
Why not simply look at it this way: In your JS on the other end, when you are doing validation, have the last check a check to verify that a header is sent - and it it passes, set a hidden field in the form to a true value - then in your PHP you can check that particular element without having to worry about every possible header that is sent.
if(!count(preg_grep('#^header\d+$#',array_keys($_POST))))
{
//no header submitted
}
This will allow to use a RegExp as requested, but I also would prefer the solution by jpic
I have this select input in my form that I want to access via PHP.
<div data-role='fieldcontain'>
<label for='fruits' class='select'>Favorite Fruits</label>
<select name='fruits[]' id='fruits' multiple='multiple' data-native-menu='false'>
<option value=''>Favorite Fruits</option>
<option value='1' selected='selected'>Apple</option>
<option value='2' selected='selected'>Banana</option>
<option value='3' selected='selected'>Cherry</option>
</select>
</div>
By setting the name of the select element to "fruits[]", this works:
// |$fruits| is an array
$fruits = $_POST['fruits']
However, I am concerned about cleaning data from the form. Feeding post data into an array sounds insecure. What if, for instance, someone changes the select element into a text input element via Firebug and inputs malicious code into my program? I never call htmlspecialchars.
Are my security concerns valid? Why or why not?
They are valid indeed, if the data comes from the user input you need to sanitize it first.
In this case, a user can easily break your HTML or, even worse, inject some malicious XSS attack.
You need to sanitize the values, htmlspecialchars is enough in this case.
Nevermind, I understood you were populating the HTML select tag with options from user input, but this is not the case. PHP will only accept strings or arrays in POST data, so you need to make sure the data coming in is compatible with what you want to do with it. One possible solution would be to white-list the submitted values, functions like array_intersect might be useful here, for instance:
$allowed_fruits = array('Apple', 'Banana', 'Cherry');
$fruits = array_intersect($allowed_fruits, $_POST['fruits']);
This way, if the user submits "Strawberries" it will be ignored on the $fruits array.
You might also want to make sure that the array isn't multidimensional, like this:
if (count($_POST['fruits']) != count($_POST['fruits'], COUNT_RECURSIVE))
{
// array is multidimensional, do not process
}
This of course, depends on your usage of the data but the white-list approach is always the most secure.
Your code should be validating whether user input is in the expected format (isset, is_array, ...) and properly escaping it before sending it to the database, html output, logs, wherever else. Fundamentally there is very little difference in here between a user entered string and user entered array of strings.
Use mysql_real_escape_string (or even better PDO) to work with the database, htmlspecialchars to work with HTML output.
That is the correct way to get the values, however, you are right to worry. You receive the values the way you suggest, then you use an appropriate method of sanitation: htmlspecialchars for displaying, mysql_escape for inserting into your DB, etc. You'll need to do that for each element in your array, but only at the time you're going to use it.
I've got a form that contains contact info. Each has a type, and then the contact information itself. For example:
Type | Contact
-------------------------------
cell | 555-555-5555
home | 444-444-4444
email | abc#def.com
It's a functional requirement that users can add/remove contacts from the form using jQuery (showing only the contact info that exists - i.e. it's not a static contact form).
Since users can add/remove any row they like in the form, this produces HTTP parameters similar to the following (with numbers that are not sequential, and may not be contiguous):
contact_ty3=cell
contact3=555-555-5555
contact_ty994=home
contact994=444-444-4444
contact_ty45=email
contact45=abc#def.com
Therefore, numbers after the contact and contact_ty parameters are arbitrary, except that they serve the purpose to match up the type to the associated contact information.
So, on the receiving end, in PHP, how to I efficiently process the parameters, using the numbers to match up the types and contacts? I'm thinking the best way to do this would be via regex, but the simplest function I can think of iterates through the entire $_REQUEST array, strips out the parameters that start with contact, and go from there.
Is there a more efficient way? Seems like I'm writing a manual string/param parsing method, when perhaps there's a function to do this that I simply don't know about. Since I won't know the precise names of the form parameters beforehand, I can't rely on the assumption that there will be a contact1, contact2, etc.
With some clever naming you can easily match them up on post:
<select name="contact[3][type]">...</select>
<input name="contact[3][value]" ..>
<select name="contact[994][type]">...</select>
<input name="contact[994][value]" ..>
<select name="contact[45][type]">...</select>
<input name="contact[45][value]" ..>
And in PHP
<?php
foreach($_POST['contact'] as $id => $data){
echo "$id => type is {$data['type']}, value is {$data['value']}";
}
Iterating $_POST or $_GET is a good idea, not $_REQUEST as it might contain cookies. However, its best not to use regex. You can use substr for this purpose. Observe
foreach($_GET as $k=>$v) {
if(strpos($Haystack, "contact") === 0) {
//process $k
}
}
The form that will be submitting the data will have somewhere between 10 and 100 values being sent to the PHP file. The number of inputs is stored in a variable called count within my javascript function but I don't know how to transfer its value to my PHP file.
Another idea I had was to have a while loop that detected a null value and to have a counter within the while loop to keep count.
How should I handle this?
No need to submit the count. You can just submit your dynamic number of values as an array. You can use the PHP array notation in your name attributes:
Input 1: <input type="text" name="myvar[]" />
Input 2: <input type="text" name="myvar[]" />
...
Input n: <input type="text" name="myvar[]" />
On the PHP side, $_REQUEST['myvar'] will be an array.
Without knowing more about your implementation, I would suggest the latter of your two options: use PHP to loop through your $_POST array and count the valid values you have. This is the best option as it is more secure and reliable.
I think there might be a more "correct" way to do this, but what I would do (without knowledge of a better way) is have a hidden form element something like
<input id="hidden_count" type="hidden" name="count" value="" />
And then have a function called onsubmit that sets this value and returns true to tell the form to continue
(with jQuery)
function onSubmitFunc(){
$('#hidden_count').val(count);
return true;
}
I'm sure there's a more elegant solution, but that should work for what you need.
If you have access to Javascript, the easiest by far would be to turn your data into JSON on the client side, send it to the server as a single string variable, and use json_decode on the server to get the properly formatted value back. You can react to the submit event on your form to have the Javascript compute the JSON before the data is sent.
Otherwise, you can have the Javascript output the number of fields to a specific hidden variable within your form. The server can then read that value, and look for the data by key in its input.
I guess you use javascript for creating the additional input element, if you just name ascending, you could use count to loop through the $_POST data. Or else use a hidden element form for counting the new input elements and post it, that way you have the correct number, and know how long you should be count.
Maybe I am not getting this, but if count in your JS file corresponds to the number of input elements in the form which is send to your PHP file, why not count() them on the serverside. The data will be in the $_POST array.