Using Jackson JSON View to Protect Mass Assignment Vulnerabilities

We use JAX-RS to develop Restful Web Service and only consume and produce json data with Jackson.

In our model class(ModelA), there may be cases that:

  • Some fields are only viewable but not editable  - Client can view them but can't edit it, they are maintained by backend logic
  • Some fields are totally internal, shouldn't even return to client, and client is not allowed to edit.

We need use code to implement this logic, express what fields are viewable only, what fields are editable, and what fields are internal in whitelist mode; otherwise we may expose some security issue. - Check Mass-Assignment Vulnerabilities... Or How Github Got Hacked

Solution - Jackson @JsonView
We can create JSON view like below:
public class View {
    public static class Editable {}
    public static class Viewable extends Editable {}
    public static class Internal extends Viewable {}

Then annotate our mode class:
@JsonIgnoreProperties(ignoreUnknown = true)
public class Model implements Serializable {

 protected String editableField;

 protected String viewableField; 

 protected String internalField;

At last, we annotate out jax-rs resource with @JsonView annotation.  
 @Produces(MediaType.APPLICATION_JSON )
 public Iterable<Model> search() {}

 @Produces(MediaType.APPLICATION_JSON )
 public Model getModel(@PathParam("id") final String id) {}

 public Response add(@JsonView(View.Editable.class) final Model model) {}

In JAX-RS, if one model(either request or response) is annotated with @JsonView(View.Editable.class), in our case add method, Jackson will only serialize or deserialize fields that are annotated with @JsonView(View.Editable.class).
In our case, client can only pass editableField, if client pass any other fields, server will just silently ignore them.

If one model (either request or response) is annotated @JsonView(View.Viewable.class),  then Jackson will serialize or deserialize fields that are annotated with both @JsonView(View.Editable.class) and @JsonView(View.Viewable.class). child(Viewable) inherits view membership from parents(Editable).

In both cases, Jackson will not serialize or deserialize fields that are annotated with  @JsonView(View.Internal.class). So they are protected.

In our service implementation: in add method, we need make sure we add these non-editable fields; in update method, we may have to read and merge these non-editable fields from old value from database to the new value.

-- One trick: Don't mix-use @JsonIgnore and @JsonView, seems this will confuse Jackson, the field will be serialized or deserialized in all cases.

Spring MVC provides data binder that we can specify what fields are not allowed.
@InitBinder public void initBinder(WebDataBinder binder) { binder.setDisallowedFields(DISALLOWED_FIELDS); }

Read More
Jackson Essentials - the JSON Libaray
Using Jackson JSON View to Protect Mass Assignment Vulnerabilities
Merge JSON Objects: Jackson + BeanUtils.copyProperties
Jackson Generic Type + Java Type Erasure

Jackson Date Serialize + Deserialize
Mass-Assignment Vulnerabilities... Or How Github Got Hacked
Mass Assignment, Rails, and You


adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)