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;
Related
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.
With that said, there is a question that seems to be asked a lot and has answers - but I'm not a programmer 'enough' to understand all the different explanations. I was hoping for something more clear and concise to my very specific example and need.
I have two forms. (I might also add this is being used on Wordpress)
One form is on the first page and will collect age, home value, and debt owed - all in drop down select fields.
The second form is on the next page and will collect other contact information and upon submit - will post all the fields to my CRM.
I have been able to successfully get the data from the first form into a query string on the page of the second form. But try as I might - I just can't figure out how to get the field data from the query string into my field forms. (Both display or pre-populated and as a value ready to be submitted once the rest of the fields are completed.)
Here is an actual query string:
http://example.com/2-form-test-2-of-2/?age=75&value=572%2C500&lien=107%2C500&sendbutton=#.UYSBEKKG2So
I simply need to get "age" - "value" and "lien" from that query string showing in the fields on the 2nd page. Simple is best - even if it's 'hack-ish' as I will most likely just include the code directly on the Wordpress page that includes this form.
One possible solution is to add a piece of javascript that gets fired on page load and:
1) disables form post button
2) populates form fields with values from URL
3) enables form post button
If these values are just suggestions for user, which he could easily change before posting — this should work.
If, on the other hand, these values are internal and unchangeable by user, you should not expose these in editable form and allow user to change those by editing URL or form posting (but including these as read-only page fragments is apparently ok).
This is place for only programmers. To become a programmer, please refer some online resources and ebooks. without knowing basic concepts, you can't understand anything.
even after understanding basics, if you have doubts, you can ask here, providing the code samples you have developed.
Is it possible to validate the Xpage's ACL depending on the Source document's field value.
We need to make the Authors & Readers ability at XPage level (as per requirement I am not supposed to use the ROLES, since, it is dependent on each individual Authors which is stored in backend document FIELD).
Kindly suggest the approach, as I am not even looking HideWhen for the Buttons(edit,save etc)
Example code in the ACLEntry[0] in Xpage:
if getComponent("inputText1").getValue() == sessionScope.user {
session.getEffectiveUserName();
} else {
return false;
}
Thanks.
I do not quite understand your code on that property...
To query the readers/authors level at XPage level I suggest to use the database.queryAccess method (http://www-10.lotus.com/ldd/ddwiki.nsf/dx/NotesDatabase_sample_JavaScript_code_for_XPages?opendocument&comments#queryAccess)
You try to compare the username only. This may fail if your access level is computed by a membership in a group where your username is not relevant.
XPages' ACL depends on the database ACL, so you have to setup the levels there - the XPages' ACL is in addition to the "real" ACL as far as I experienced.
I also experienced that readers fields affect the ability to use an XPage to open a document by default.
I hope my answer is not too confusing ;-)
I think the question is valid (to my current knowledge):
If I want to design a workflow application but the current approver should not edit the full document I want to give him only access to parts (ie. a comment field and the approval button).
The question above relateds somehow to access controlled sections in old LN development. I so far also didn't find a good solution
What you describe is a very common workflow scenario. There are several ways how you can implement that efficiently. Here is what I would do:
Have one (or more) custom controls that render the "payload" (the fields the requester fills in)
assemble them into one bigger control that is used to render the form
compute the mode to read/edit depending on who is opening the form and the mode (new, pending approval, approved, rejected etc.)
Optional: when submitted remove submitter from the author field
Have one "Approval Control" that show only when the current user is the (current) approver and status is "pending approval" That control has fields that are NOT bound to the document, but a scope variable
The approval button triggers SSJS that takes the scope variable values and updates the document (and triggers notifications, access change etc)
The approval component can be used for any approval form. You then can contemplate not to give the approver write access since you could handle that in code.
What I need
I have a custom Entity with that with multiple fields. Admin Role has "god" access. All other roles except for one have read only. The one non admin role with update access, should only be able to update a single field.
What I believe to be true
I believe I have three main options to implement this requirement:
Enable Update Access to the role for that entity then write Javascript to disable all fields on the form for that role, except for the one that I want that role to be able to edit
Enable Update Access to the role for that entity then create a new form that disables all fields on the form for that role, except for the one that I want that role to be able to edit.
Enable Update Access to the role for that entity then turn on field security for each field, disabling access using the field security, for each field except for the one I want them to edit.
What's the Best Practice?
What options should I choose?
If I go with options 1 or 2, will the user be able to edit the field on the bulk edit form?
From a user perspective, I think it's confusing when a form opens up with things enabled, then they get locked down. Plus someone could possibly get data in there before the fields get locked. I'd say you'd have to combine this with a plugin to prevent changing fields you don't want changed.
I like this option better, although again, the field can be unlocked if someone knows what they're doing, so a plugin to double check would be nice.
This would avoid having to double check in a plugin, but you also have to rely on the admin correctly setting up security for new fields going forward. If that's not a concern, this might be best.
Bulk edit is a global privilege, so they'd have bulk edit for all entities. Also, the bulk edit form does not load scripts, so that knocks out option 1. I'd say if it's just this one field, I might leave the privilege locked down and provide my own Bulk edit button on the grid that would show a custom page that just has that one field on it, then handle the updates though script.
2 is most likely best, or as an alternative put the fields in the header or footer rather than as read-only fields on the form.
This also means the fields won't be available to bulk edit, but other methods such as data import or workflows would let users get round this if they know how and have rights to do such things.
3 Field Security is the most robust and works for all scenarios
Possible option 4: create another entity to contain those fields and apply different security to that entity. If created as a child, show the record in a grid on the form with the values included in the view. If it is a parent then you could use methods such as showing the values via an HTML webresource page included on the form.
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