How to prevent hidden fields with ID from getting hacked
playframework
Solution
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.
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:
public static void someActionDisplayingForm(){
SomeObject o = ....
SomeOtherObject o2 = ....
String constants = o.id + "|" + o2.id;
String hash = Crypto.sign(constants);
render(o, o2, hash);
}
in the template you have
#{form ...}
<input type='hidden' name='id1' value='${o.id}' />
<input type='hidden' name='id2' value='${o2.id}' />
<input type='hidden' name='hash' value='${hash}' />
in the method processing the form you'll do
public static void processing(String id1, String id2, String hash, String otherValues, ...){
String constants = id1 + "|" + id2;
String checkHash = Crypto.sign(constants);
if(!checkHash.equals(hash))
badRequest();
...
}
Hope that helps.
Problem
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.