Should I sanitize user input upon 'before_validate' or 'before_save'? - security

If I receive user input, does it make any difference if I validate first and then sanitize before saving it to the database?
Or is there any risk in validating unsanitized input?
(when I say 'sanitize' I mainly mean stripping out any HTML tags)
UPDATE & CLARIFICATION:
I wouldn't put HTML tags into the database. I would sanitize the input before saving it - but after validating against my model. The reason the validation and sanitization are separate is because they are separate libraries - the only question is whether I should call 'sanitize' upon 'before_validate' or upon 'before_save'.

The only risk I can think of is if you are performing extensive client-side validation. If you were validating and then spitting the values back onto the page in your error messages then you could have an issue.
For example, if you have a textbox that has to only contain numbers and a user enters a letter in that textbox. If your client side script generates an error message like " 'somevalue' is an invalid value for this textbox ", then you are injecting whatever the user has entered into the box back onto the page. Either way, it will only affect that user's session.

Why are you separating HTML stripping (or escaping) from other validation? Isn't it all the same thing?
And why would you put HTML tags into the database only to strip them later? Doesn't that mean that your database is temporarily incorrect?
I don't see why you're separating "validation" from "sanitize". They're two sides of the same coin. Do everything you can to make sure the data is perfect before committing it to the database.
"the only question is whether I should call 'sanitize' upon 'before_validate' or upon 'before_save'."
The distinction is too subtle for words. You must do both. Generally, you do not want to try and validate HTML.
Therefore, it's only sensible if you (1) "sanitize" to strip HTML tags and then (2) validate what's left.
I'm not sure how else you could do it.

ALWAYS validate and sanitize before submitting to the database. Without doing so, you could expose your database to SQL injection attacks.
What order you do so depends on what you want your user experience to be. If you validate first, then you could provide validation back to the user easier (You could use javascript and regular expressions to do this)
Required xkcd cartoon:

Related

How to implement 'if' in Gherkin

I am trying to convert Selenium test to Gherkin. Is there way to implement if statements in Gherkin?
Example : assume the code is written in the below format. I am just writing description as below. Please understand the part after double slash is the actual Selenium code:
// launch the application
// login to application
// navigate to page
String str;
if(str== "XYZ")
{
// verify title
}
//verify text field 1
//verify test field 2
//verify select box
For this I am trying to write code in Gherkin as follows
Given user launches the application
When user login with valid credentials
and navigate to required page
When String str is "XYZ"
Then verify title
And verify text field 1
And verify test field 2
And verify select box
but this code is incorrect because if the str is not equal to "XYZ" we want that title should not be verified but other verification like text field1,2 and select box should be verified.
You don't implement if in Gherkin.
Gherkin is about communication and those you want to communicate with, non coders, don't know what an if statement is. They don't care either.
The solution? Two scenarios to cover both cases.
Ideally, this level of detail would not be in your Gherkin scenario. The best approach is describe business use cases, not low level details. This is what Gherkin is designed for: communicating with non-technical stakeholders so that you can work out if you are building the right thing in the first place. Here is what I would write:
Given the user is logged in
And the user is on the required page
When they enter data that requires the optional fields to be validated
And they enter invalid data in the optional fields
Then the form shows an error on the optional fields
The low level details don't matter (that the string is specifically "XYZ" or that it is the title field is not important), so these should be hidden in the step definition and/or unit tests.
In order to continue to check the other fields, you can just add another step after this:
When they enter invalid data in all of the other fields
Then each other field has an error message attached to it.
Again, there is no need to specify the actual fields, or separate them into their own steps. The idea is to express the high level business value of the scenario, i.e. that the form is validated when it should be.
The advantage to keeping things high level is that when the form changes (as it eventually probably will), then this scenario can remain untouched. Which is correct as the business case is the same: it should validate when it's supposed to. All the changes will be in the step definitions. This means that there is no reason to have another discussion with your stakeholders about whether your scenarios are still testing the right thing.
You can write the scenario, somewhat like this:
Given the user launches the application
When user login with valid credentials
And navigates to required page
Then he should see the page datails
Inside the Then step you manage all the logic.
Then(/^he should see the page details$/) do
if condition
...
else
...
end
end
Gherkin is not a programming language to use if or else conditions. It is a part of BDD framework, that is implemented, to make the stakeholders and other non technical resources understand what the test process is about. Hence, it is always recommended, you keep the gherkin as simple and as generic as possible.
Strictly speaking you should create an alternative statement along the lines of:
Given user launches the application
When user login with valid credentials
and navigate to required page
When String str is NOT "XYZ"

MVC 5 Save Drafts While Ignoring Missing Required Fields

I have searched for current solutions, but can't find a set of guidelines or examples as to how to achieve the following:
The original requirements involved models with required fields, so we included annotations to those fields. As usual, there is a last-minute change and we are being asked to allow the users to save drafts. These drafts must allow the user to save the forms without any of the required fields.
I would like to know what the best practices for this problem are.
Solutions I am considering, but I accept they might be a hack (and that's why I am asking the experts)
If the user clicks "Save as Draft" I can capture the fields that have information in another ActionResult and run basic validation on those fields. Since there is a chance that required fields are missing, I am thinking in storing the captured info in a temporal model (without any required annotations). If the user decides to edit such form, I can populate fields in the view with the temp. model until the user clicks on "Submit"
Another option is to remove all required annotations and run client-side validations... but am wondering on the amount of work required to do so.
Any thoughts are very much appreciated.
Just have 2 save methods. 1 which is called from the autosave and 1 that is used to submit the process. In the autosave method do not check if(ModelState.IsValid).
Whether you choose to save the incomplete objects to the same table or a different table is your choice. In a relational world I would likely use a separate table, in a non-relational world I would use a singular object collection.
This will allow you to keep the same set of original models. There is a very high cost to duplicating your models, there are certainly times that warrants pass by value/copy but make sure the cost of mapping is there. In this situtation I do not believe there is value in mapping, except perhaps at the persistence level if you need to map to a different object because of an ORM's constraints.
There is deep value in these partial forms. Recording this on the server will allow you to apply analytics to learn why your users abandon your processes. It also gives you the ability to follow up on users who leave incomplete forms such as sending a reminder (nag) email.
You don't want to save anything to your database until it is complete. Having a duplicate table where everything is nullable is cludgy as hell. Before HTML5, the typical path was to save the information to the session, which you could then pull from to refill the fields, but that's requires having a session with a relatively high expiry to be useful.
Thankfully, HTML5 has local storage, which is really the best way to handle this now. You just watch for onchange events on your fields and then insert that value into local storage. If the user submits the form successfully, you destroy the local storage values. Otherwise, you attempt to read those values from local storage when the page loads and refill the fields.
See: http://diveintohtml5.info/storage.html
There's pretty broad support, so unless you need to worry about IE6 or IE7, you won't have any issues.
Another option (depending on your data obviously) would be to comply with the database but not the model. By this I mean ignore Model.isValid and disable Javascript validation on the front end but then satisfy the database table. In a form, you mostly have:
textboxes - default to "" or " "
checkboxes - easy true/false default
radio buttons - one is probably already selected
dates - default to DateTime.MinValue (or DateTimeUTC)
enums - default to 0 (usually for 'unspecified')
Hopefully you are also saving a flag designating that it is in Draft state so that you know you need to interpret the 'null codes' you have set when it comes to displaying the semi-populated form again.

solution for: select input, dropdown tampering prevention

for hidden field tampering protection: Id, RowVersion, I use a version of Adam Tuliper AntiModelInjection.
I'm currently investigating a way to prevent tampering of valid options found in select lists/drop downs. Consider a multitenant shared database solution where fk isn't safe enough and options are dynamic filtered in cascading dropdowns.
In the old days of ASP.NET webforms, there was viewstate that added tampering prevention for free. How is select list tampering prevention accomplished in ajax era? Is there a general solution by comparing hashes rather than re-fetching option values from database and comparing manually?
Is ViewState relevant in ASP.NET MVC?
If you can, the single solution here is to filter by the current user ids permission to that data, and then those permissions are validated once again on the save.
If this isn't possible (and there are multiple ways server side to accomplish this via things like a CustomerId fk in your records, to adding to a temporary security cache on the server side, etc) , then a client side value can provide an additional option.
If a client side option is provided like was done with Web Forms, then consider encrypting based on their
a.) User id plus another key
b.) SessionId (session must be established ahead of time though or session ids can change per request until session is established by a value stored in the session object.
c.) Some other distinct value
HTTPS is extremely important here so these values aren't sniffed. In addition ideally you want to make them unique per page. That could be the second key in A above. Why? We don't want an attacker to figure out a way to create new records elsewhere in your web app and be able to figure out what the hashes or encrypted values are for 1,2,3,4,5,6,etc and create essentially a rainbow table of values to fake.
Leblanc, in my experience, client side validation has been used mostly for user convenience. Not having to POST, to only then find out that something is wrong.
Final validation needs to occurs in the server side, away from the ability to manipulate HTML. Common users will not go on to temper with select lists and drop downs. This is done by people trying to break your page or get illegal access to data. I guess my point is final security needs to exist in the server, instead of the client side.
I think a global solution could be created given a few assumptions. Before i build anything I'll like to propose an open solution to see if anyone can find flaws or potential problems.
Given all dropdowns retrieve their data remotely. - in an ajax era and with cascading boxes this is now more common. (We are using kendo dropdowns.)
public SelectList GetLocations(int dependantarg);
The SelectList will be returned back as json - but not before having newtonsoft serialization converter automatically inject: (done at global level)
EncryptedAndSigned property to the json. This property will contain a Serialized version of the full SelectList containing all valid values that is also encrypted.
EncryptedName property to the json. This property will have the controller actionname - For this example the EncryptedName value would be "GetLocations"
When the http post is made EncryptedName : EncryptedAndSigned must be sent in the post also. For this JSON POST example it would be:
{
Location_Id: 4,
GetLocations: 'EncryptedAndSigned value'
}
On the server side:
[ValidateOptionInjection("GetLocations","Location_Id")
public ActionResult Update(Case case)
{
//access case.Location_Id safety knowing that this was a valid option available to the user.
}

Does CakePHP automatically deal with mass assignment vulnerabilities when saving modified data?

Edit:
After receiving more information from DCoder, the phrase I was searching for here is a "mass assignment vulnerability." That is to say, taking advantage of the convenience of methods that would save all valid fields to the database, regardless of their presence on the initial form (making them vulnerable to manipulated POST data containing more [possibly more critical] fields than the intended ones).
The two common responses are then appropriately named whitelisting and blacklisting; whitelisting fields intended for modification, or blacklisting fields that should not be modified.
My question then follows: does CakePHP automatically whitelist only those fields in the submitting form, or is it necessary for me (and other Cake fans) to be careful that we are whitelisting or blacklisting appropriately?
Original Question:
Cake offers a lot of great ways to generate forms and handle them nearly automatically. As I was thinking about security, I got to wondering: is Cake aware of what fields existed in a form submitted, or will it simply accept any valid field? Take the following senario if I'm not making sense (and someone is welcome to edit my question to be better worded if they can think of a better way to express it):
Let's say I allow my users to edit their profile. I create a form which has fields for username, e-mail, and password, under the action edit.
A clever user wants to come in and change their is_admin field from false to true, so they use an app like firebug to submit custom post data to the edit action, which includes the field is_admin set to true.
The question is, would Cake realize on it's own that is_admin was not in the original form, or do I need to be careful to explicitly specify the only fields which fields a given action can modify? Is there an easier way?
Thank you!
James
You have to load the SecurityComponent in your controller(s) and CakePHP will prevent form tampering for you, see http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#form-tampering-prevention
CakePHP has built in validation option available. The Form automatically generate the fields and do validation based on the validation criteria you have mentioned in the model. This validation will be called automatically before the Save method.
Also if you want to add some custom validation, you can add that in the model.
With your specific query you can remove the is_admin field from the edit form so that it won't be editable to the user. If you want to add more security and make sure that the is_admin field has false value you can edit its value in the controllers edit method.
In the edit method you can add the following code before calling the Save action.
$this->request->data['ModelName']['is_admin] = false;

Zend form: secure way store entry ID when editing?

I'm new to the Zend Framework and I have a problem to create an edit form with the Zend_Form.
My problem is that I need to store the entry ID during editing, I've seen some examples that are using a hidden form field, but a hidden field can be manipulated by a user.
So: how can I set a form field which gets populated by $form->populate($data); and is available after submiting the request but is not editabel/visible to the user in any way?
Thanks for any help!
I'm not sure if there's really a point in trying to hide the value.
Consider the following:
To display the correct editor form, you need the ID of the object that is to be edited.
Before allowing the user to edit a certain ID, you would check if the user can edit it or not.
Thus, if you put the ID in the form, it shouldn't really matter:
When you POST the edit form, you should again check that the user can still edit the ID.
If the user changes the hidden ID, it doesn't really matter. They could still go and edit the other ID by finding it on the site. (This is assuming your check didn't tell you the user does not have access)
what kind of data you wanna hide?
data should be in post or get.if you dont put your data in your form,then you will have to use GET which is less secure than POST.
If you have some data and you dont want the user to see those data,then you should not put those data in a form.you can store and retrieve hidden data using forms submitted values.lets suppose your hidden field is users password.you dont need to send password back to the client when client is editing the form.you can manipulate password in your controller according to the user`s submitted first name and last name.
If you still insist, you may wanna try encrypting data using ZF and echo ing your value and setting encrypted data into a hidden form element.
Zend_Form generates an HTML form element with the form elements you specify. So its element capabilities are narrowed to a simple HTML form.
The hidden form element is used to pass those data that the user is not supposed to enter by hand. But as you yourself said it, there is no guaranty it could not be tampered. so no security is provided by using a hidden form value.
Most of times you'd better use server side values (like stored in sessions) to reference to values that are to be protected from user.
I suggest you keep the ID in a session value, and then you could use the session key in the hidden form field. this way the user can not change the target ID. However you are not able to use the $form->populate($values) on this in one step. you would have to set the target value with other steps:
fetch data from the session
set the form element value with the fetched data

Resources