I am building a simple CRUD app (not using the CRUD module).
My model is a simple class with one attribute. the id is implicitly inheritied from Model.
@Entity
public class Account extends Model {
@Required
public String domain;
}
The view is as follows. Please note the hidden field with id.
<form class="form-horizontal" action="@{Application.save}" method="POST">
<fieldset>
<legend>Settings</legend>
<input type="hidden" name="account.id" value="${account?.id}">
#{field 'account.domain'}
<div class="control-group #{if field.error != null} error #{/if}">
<label class="control-label" for="${field.id}">&{field.name}</label>
<div class="controls">
<input type="text" class="input-xlarge" id="${field.id}" value="${field.value}" name="${field.name}">
<span class="help-inline">${field.error}</span>
</div>
</div>
#{/field}
<div class="form-actions">
<input class="btn btn-primary" type="submit" value="Save">
</div>
</fieldset>
I have been able to build a scenario where save,update works.
The way update is done is I read the ID from hidden field, and update the record. If ID is not available, a new record is created.
So the question is: Can the ID be hacked i.e modified so that I change 1 to 2, and assuming a record with 2 exists, it gets overwritten. (I suppose it shouldn’t be difficult with firebug or other plugins).
How do I prevent this? One option I thought of is to read the record with the given Id, if user is allowed to modify it, I allow update, otherwise not. This is still not fool proof because, while the user could be allowed, “wrong” record could be modified.
I imagine this is a known problem and hopefully with a known solution.
Thanks for taking the time to answer my question.
Of course, it is possible for an attacker to change the id of the record.
there are several ways to minimize the impact of this attack.
1) easiest way – Object fetching:
Fetch the Object from the database and check if it belongs to the user in question. This will prevent other users from messing around with objects that don’t belong to them, but will not prevent a user to change another object belonging to him. This is an easy way and sufficient in most cases.
2) more complicated: signing:
The idea here is to sign the constants you provide to the template and check if the hash still matches after form submission.
This is very similar to what play does with its session. Its impossible for an attacker to mess around with the constants (e.g. id) and provides the most security.. however, you’ll have more work to do.
Example:
in the template you have
in the method processing the form you’ll do
Hope that helps.