Data Binding Threats and Security with Grails

24 / Jul / 2013 by Bansi 2 comments

Data binding is the technique of binding two data sources to maintain the synchronization of data which in reference to grails stands for binding incoming request parameters onto the properties of an object or entire graph of objects. These methods allow user to write clean and shaping code without littering the script and data with lots of details.

The two binding sources may or may not be of same properties. Request Parameters which are generally a form submission are always strings whereas the properties of Groovy may not be.

Based on the methods of binding and properties of domain class, it is divided into two ways.

Using Map Constructor: can be done using domain classes.

def save() 
{    def b = new Book(params)    b.save() }

new book(params) is used to allow data binding within itself. Grails can automatically be informed that you are trying to bind from request parameters by passing a mutable multi-dimensional map (hash) of request (CGI) parameters i.e. param object to domain class constructor.

If the request parameter is to set title and author on domain classes, it can be done as followed:

/book/save?title=The%20Stand&author=Stephen%20King

Using Property: To perform data binding on an existing property, domain class properties can be accessed using an external property known as properties which works with the same effect as implicit constructor.

def save() {
    def b = Book.get(params.id)
    b.properties = params
    b.save()
}

When a null-able constrained property is bonded to an empty string with no characters or spaces, it converts it to null as well. This particular characteristic is really helpful when a null value is desired for empty form field as a null request cannot be submitted as parameter. A default value is directly assigned to the parameter when null submission is not required.

In case of mass binding, all the strings are automatically trimmed down as default which can be disabled by setting grails.databinding.trimStrings as FALSE in grails-app/conf/Config.groovy.

// the default value is true
grails.databinding.trimStrings = false // ...

The same process can also be followed to set all empty strings to null at the time of binding by setting grails.databinding.convertEmptyStringsToNull property to false in grails-app/conf/Config.groovy.

// the default value is true
grails.databinding.convertEmptyStringsToNull = false // ...

Both these mass binding properties are followed in a sequential manner of trimming and then conversion. So if an empty string follows the process, it will first be converted to null but because of trimming in second step it will return blank again.

Though these data binding techniques are easy to implement but still they are very deleterious. The main problem with these is, even if you do not want to bind a particular string or properties, it will bind all non-transient properties without any prior intimation. As a data request is sent via form submission and not all the properties are submitted, but still there are chances that an attacker can intentionally send malign data via a raw HTTP request.

One more reason why object.properties = params is not recommended is: If a user is given option to edit their profile with nothing but their first name and last name only, they can easily edit the DOM of their page or include an isAdmin input and make himself admin.

With successive attempts, Grails came up with a security solution to this. To avoid such malicious practices, below mentioned methods have been enforced:

  1. Limiting the properties

To restrict clients from persisting a malicious binding of data and domain class, pre-defining a list of properties using subscript operator, allowed to bind to a particular properties can be exercised.

def p = Person.get(1)
p.properties['firstName','lastName'] = params

The above mentioned will allow only first name and last name to be bind and rest will automatically get excluded.

Data Validation using Command Object for data binding can also be used instead.

       2. bindData method

Parameters that you do not want to update in domain classes can be easily excluded; allowing other parameters to go through using bindData method.

def p = new Person()
bindData(p, params, [exclude: 'dateOfBirth'])

The same method can be used for certain properties exclusively too.

def p = new Person()
bindData(p, params, [include: ['firstName', 'lastName']])

Binding fields depends on the value of include, if it’s an empty list then all the fields will be subject to binding if not excluded.

With latest versions of Grails, new and incredible features are being imparted to the existing binding mechanism outdoing previous versions. Some of these are:

  • Large amount of data-binding capabilities are to be supported.
  • Compatible in previous versions of Grails applications and plugins
  • Better performance
  • Designed for easy tractability
  • Clean and User friendly interface
  • Compatible on platforms with no map intermediary as well like JSON and XML
  • Assignable IDs to be provided for domain objects binding.
FOUND THIS USEFUL? SHARE IT

comments (2)

  1. Vivek

    Alternatively, one can use the “bindable” constraint for versions of grails > 2.0.2 to specify whether a field is bindable or not. By default, transients, static fields and dynamically typed properties. You can refer grails.org/doc/latest/ref/Constraints/bindable.html for more details on this.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *