There should be a Request hash check when objects are modified
The developer programmed a form to edit a "Customer", and he can select one role from a dropdown list.
This field will have the following name: customer[role], and its expected value will be a UUID.
Now, if an attacker replaces this form field by some fields which are named like:
customer[role][__identity] = ...
customer[role][isAdministrator] = TRUE
... he is able to completely change related domain objects which is like SQL-Injections "built right into the framework". Nice, eh? :-)
How to solve this issue?¶
The general idea: If an object is modified, make sure that the appropriate form fields have been rendered on the last request. Else, it might be an attack.
We build a list of all form fields which can be submitted. This list is signed/hashed (with a private key), and the list and the hash of the list are sent in a parameter called __hmac to the server as well.
If the parameter __hmac is set, it verifies the signature and checks that all submitted fields are also inside the form field list. If this is the case, the parameter "hmacVerified" inside the Request object is set to TRUE.
Remember we only wanted to enable this feature when data was modified? That's why we modified the Argument to remember the origin of the data (which could be directly from the client, from the persistence layer but unmodified, from the persistence layer and modified, and a new object).
If any argument has been mapped with the cases "persistence layer and modified" and "new object", we make sure the HMAC was validated correctly. If the HMAC was not validated correctly, an exception is thrown.
How to disable it¶
For building public APIs, a new annotation @dontverifyrequesthash has been introduced. If you annotate your action with this annotation, no HMAC error will be thrown at all, but you have to care about such security issues yourself.