Field-level validation on any change - java

Hibernate's validation (hibernate-validator) does validation when #Entity is being persisted (before). That is not enough as I want seamless validation on business layer.
So the goal is to validate fields on any change - meaning that e.g. #NotBlank applied to field will throw an exception whenever I call this.field = value; with blank variable (without calling outside validation service, so basically an aspect).
Based on my knowledge on AspectJ, there should be an existing possibility for javax.validation annotation applied on fields to be making them on-change sensitive.
My question is - what tools do I use and how do I configure them or what am I even looking for (I have no knowledge on this spec nor its implementations)?
My backend stack is Spring (Boot) with JPA (Hibernate) that ships with mentioned hibernate-validator, what else do I need to make my goal work with least code/config?
EDIT
To give example:
#NotBlank
private String name;
public void setName1(String name)
{
System.out.println("CHANGING 1");
this.name = name;
System.out.println("PASSED 1");
}
public void setName2(String name)
{
System.out.println("CHANGING 2");
this.name = name;
System.out.println("PASSED 2");
}
...with call:
public void test()
{
String newName = " ";
entity.setName1(newName);
entity.setName2(newName);
}
Should print:
CHANGING 1
and:
public void test2()
{
String newName = " "l
try { this.entity.setName1(newName); } catch (Exception e) { }
this.entity.setName2(newName);
}
Should print:
CHANGING 1
CHANGING 2
I thought of using private setter like:
private void setNamePriv(String name)
{
this.name = name;
}
private void setName1(String name) // or setName2
{
this.setNamePriv(name);
}
...but then I still don't know how to make name argument checked for #NotBlank when method is ran. Apparently syntax:
private void setNamePriv(#NotBlank String name)
{
this.name = name;
}
...is supported, but what library/configuration actually would make it work (currently used hibernate-validator doesn't do it by default).
Then again - using private setters introduces more boilerplate code across all entity classes and I am already using lombok to make those setters. Would have to make public setters with lombok and private myself or other way around.
What technology (library/config) am I looking for here?
EDIT 2
To clarify even more - I do know the reasons why it's not supported out-of-box:
Spring AOP uses proxies and does so only on #Beans (which are proxied).
For validation to take place #Bean (e.g. #Component or #Service) must also have #Validated.
As described that is a no-go, since e.g. #Entity is not a #Bean. As mentioned, I am probably looking for AspectJ solution but apparently there is nothing I could find. I don't think writing own aspect is that hard for this, but how come i can't find existing solution?

Related

How to fix Mass Assignment: Insecure Binder Configuration (API Abuse, Structural) in java

I have a Controller class with the below two methods for finding a doctors (context changed). Getting the
Mass Assignment: Insecure Binder Configuration (API Abuse, Structural) error on both methods.
#Controller
#RequestMapping(value = "/findDocSearch")
public class Controller {
#Autowired
private IFindDocService findDocService;
#RequestMapping(value = "/byName", method = RequestMethod.GET)
#ResponseBody
public List<FindDocDTO> findDocByName(FindDocBean bean) {
return findDocService.retrieveDocByName(bean.getName());
}
#RequestMapping(value = "/byLoc", method = RequestMethod.GET)
#ResponseBody
public List<FindDocDTO> findDocByLocation(FindDocBean bean) {
return findDocService.retrieveDocByZipCode(bean.getZipcode(),
bean.getDistance());
}
}
and my Bean is :
public class FindDocBean implements Serializable {
private static final long serialVersionUID = -1212xxxL;
private String name;
private String zipcode;
private int distance;
#Override
public String toString() {
return String.format("FindDocBean[name: %s, zipcode:%s, distance:%s]",
name, zipcode, distance);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
As per all the suggestions found so far, they are suggesting to restrict the bean with required parameters only by something like below :
final String[] DISALLOWED_FIELDS = new String[]{"bean.name", "bean.zipcode", };
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(DISALLOWED_FIELDS);
But my problem is all the 3 parameters of the bean will be used in either of the method supplied on Controller.
Can someone please suggest some solution for this. Thanks in advance.
InitBinder can be used for methods. You can try this.
#InitBinder("findDocByName")
public void initBinderByName(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"distance","zipcode"});
}
#InitBinder("findDocByLocation")
public void initBinderByZipCode(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"distance","name"});
}
i was facing same issue, then i added below code in same rest controller class:
#InitBinder
public void populateCustomerRequest(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{});
}
now its working fine for me and mass assignment issue was fixed.
Simple question - how your mapper can instantionate the bean? Here is answer / example. You can pass that data by query parameter, or in header. However that would be strange. Better is to have that methods with #QueryParam providing location, or name. That way it will be easier to protect your application.
As a side note, query has limited length, so if your search form is big and strange, #POST can be good idea, and that way you can pass all the data. For this, simple example that would be overkill.
This looks like an unfortunate false positive. The rule behind this error is made to avoid that properties present in an object but not intended to be (unvalidated) user input are accidentally populated from a web request. An example would be a POST request creating a resource. If the request handler takes the full resource object and fills only missing properties an malicious user could populate fields that she shouldn't be able to edit.
This case however does not match the scheme. You just use the same mechanism to capture your different arguments. Additionally populated properties will not even be read. In
GET http://yourhost/findDocSearch/byName?name=Abuse&zipCode=11111
the additional zipCode would just be ignored. Therefore the assumed risk is not present here.
To fix the warning, you could mark it as a false positive (if this is possible inside your setup). If that is not possible you could also just map the query parameters to method arguments directly. As you only have limited parameters that should not harm too much. If this is also no option you probably need to figure out the exact algorithm your code analysis uses to figure out what checks it will recognize. Unfortunately most scanners are only able to discover a limited set of ways to do input validation.

Is it possible to build an object like this at runtime in java?

As the title says....
I want to build a POJO with four field variables and at certain runtime events create an instance of this POJO with access to possibly maybe two or three of the fields.
public class Category implements Serializable {
private String name;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Lets say I create a new Category object but I only want to be able to have access to the name field during runtime. Is there a design pattern I can use to achieve this? I thought about the strategy pattern and looked at the builder but I am still confused if I can do this in java.
Basically the overall goal is to grab an object from a database and return it as a JSON response in jax rs. But sometimes I dont want a complete object returned but only lets say halve of the object to be accessible at during certain runtime events. My apologies if this seems like a dumb question but I know what I want to do but just don't know the best way.
I have the same problem with you, and my project was used springmvc,and the json tool is jackson.With the problem solved, I just use #JsonIgnore.For more details,just read jackson-how-to-prevent-field-serialization
So someone correct me if I am wrong or see a better option than this...with alot of objects this can be alot of extra code for serialization and deserialization...Jackson Provisions is what I need. I can use the annotation #JsonView(DummyClass.class) on the field variable. I will accept this a the best answer in a day or two unless someone else posts a better response.
// View definitions:
class Views {
static class Public { }
static class ExtendedPublic extends PublicView { }
static class Internal extends ExtendedPublicView { }
}
public class Bean {
// Name is public
#JsonView(Views.Public.class) String name;
// Address semi-public
#JsonView(Views.ExtendPublic.class) Address address;
// SSN only for internal usage
#JsonView(Views.Internal.class) SocialSecNumber ssn;
}
With such view definitions, serialization would be done like so:
// short-cut:
objectMapper.writeValueUsingView(out, beanInstance, ViewsPublic.class);
// or fully exploded:
objectMapper.getSerializationConfig().setSerializationView(Views.Public.class);
// (note: can also pre-construct config object with 'mapper.copySerializationConfig'; reuse)
objectMapper.writeValue(out, beanInstance); // will use active view set via Config
// or, starting with 1.5, more convenient (ObjectWriter is reusable too)
objectMapper.viewWriter(ViewsPublic.class).writeValue(out, beanInstance);
This information was pulled from http://wiki.fasterxml.com/JacksonJsonViews
with jackson 2.3, I can do this with JAX-RS
public class Resource {
#JsonView(Views.Public.class)
#GET
#Produces(MediaType.APPLICATION_JSON )
public List<Object> getElements() {
...
return someResultList;
}
}

Play framework 2 (Java) form data binding with nested allowed fields

Consider following model:
public class Contact {
#Required
public String name;
#Valid
public List<Information> informations;
}
public static class Information {
public String securedField;
#Required
public String email;
#Valid
public List<Phone> phones;
public static class Phone {
#Required
#Pattern(value = "[0-9.+]+", message = "A valid phone number is required")
public String number;
}
}
}
I don't want Information securedField to be affected by mass assignment vulnerability. So i decided to set array of allowedFields for Contact Form.
As i know, play forms are based on Spring DataBinder, so is it possible to handle collection fields? I don't want to write smth like:
name
informations[0].email
informations[0].phones*
informations[1].email
informations[1].phones*
etc
Following doesn't work:
name
informations.email
informations.phones*
Should i extend existing Spring DataBinder and Form classes and override bind method in this case?
Here's an arguably simpler solution. How about defining an extra constraint that will trigger a validation failure if the POST data contains any informations[%d].securedField values?
import javax.validation.constraints.Null;
public static class Information {
#Null
public String securedField;
...
}
I think that this way you can call the default bindFromRequest method instead of the one that accepts a whitelist of form field names, and still be protected against a mass assignment attack.
One shortcoming with this approach admittedly is that it would ultimately leak the names of your internal fields in the event of a concerted mass assignment attack. However if they had fairly bland, meaningless names such as securedField (no offence intended!), I'm not sure how this information could be exploited by an attacker.
Edit
If you want to allow assignment to the field based on the current user type, maybe bean validation groups could help:
import javax.validation.constraints.Null;
public class Contact {
public interface Administrator {}
public interface User {}
...
public class Information {
#Null(groups = User.class)
public String securedField;
...
}
}
Controller code
...
final Form<Contact> contactForm;
if (currentUser.isAdministrator()) {
contactForm = form(Contact.class, Administrator.class).bindFromRequest();
} else {
contactForm = form(Contact.class, User.class).bindFromRequest();
}
...
If I understand your question correctly, you can use the following patterns to whitelist nested collection fields:
informations[*].email
informations[*].phones[*].*
i.e.
form.bindFromRequest("name", "informations[*].email", "informations[*].phones[*].*");

Handling full and partial views in jersey for a REST API

I am working on creating a RESTful API for a project. I am facing a few problems trying to implement it with jersey:
My object model does not contain uri info obviously. e.g, lets say I have a Fruit class. Fruit object would have let's say a FruitName and a FruitColor. But in the response I also need to send a URI. How is this usually handled? Should I create a separate "FruitResource" that has a constructor which takes a "Fruit" and creates a full resource from it, including URI? I need URIs in the nested objects as well, e.g if I am returning a list of Child objects, I need each Child object to also have a URI, but I donlt want the URI to be part of the object model. What is the cleanest way to do this?
I want to have capability to return full and partial views of the same resource. Partial views would just have the name and the URI for example. How to get this done?
Right now what I have is a Service class that accepts the requests, which uses the DAO to create and return the objects as they are modelled from the DB, serialized to JSON using jackson.
There i a way to use JaxB class and you can pass Object Model to JaxB class and JaxB class generates URI.
The below is small prototype.
UserResource Class
#Path("/user")
public class UserResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("{user-id}")
public UserJaxB getUser(#PathParam("user-id") String userId, #Context
HttpServletRequest request) {
// now XYZ is hard-coded value
String serviceEndpoint = request.getContextPath() + "/" + "user";
UserModel userModel = new UserModel(userId, "XYZ");
return new UserJaxB(serviceEndpoint,userModel);
}
}
User JAXB Class
#XmlRootElement
public class UserJaxB {
private String name;
private String id;
private String serviceEndpoint;
private String URI;
public UserJaxB(String serviceEndpoint, UserModel userModel) {
this.name = userModel.getName();
this.id = userModel.getId();
this.serviceEndpoint = serviceEndpoint;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getURI() {
return this.serviceEndpoint + "/" + id;
}
}
User Model Class
public class UserModel {
String name;
String id;
public UserModel(String name, String id) {
this.name = name;
this.id = id;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
I'm working on a project that supports both of those concerns: https://github.com/skyscreamer/yoga with more information at http://yoga.skyscreamer.org/, including a demo.
It replaces the JAX-RS (or Spring MVC) rendering mechanism with a custom built solution that's more in tune with the needs of a REST System.
For #1, we have an annotation that you have to apply to your Child pojo. JAX-RS's annotations are meant to map URLs to controllers not to the underlying object, so we needed a custom solution... but it's really just comes down to 1 additional annotation per pojo.
For #2, we have a URL based mechanism of specifying which additional information you want from a pojo or a pojo's children (and can be nested further).
I hope this helps.
1) I'm not aware of any Jersey or JAX-RS mechanism supporting this. Seems like a bad practice to have to add the URI to the constructor for each of your domain classes, though. You could create an aspect that would intercept the method and wrap the response in a new object - adding the URI of the resource in the wrapper (you could get the URIInfo via reflection from the interceptor). I've done this when building etag support so I don't have to add cache code to every response. I suppose you could also add something in the same aspect to handle the child URI issue...
You might also want have a look at these dicussions:
http://java.net/projects/jersey/lists/users/archive/2009-01/message/357
http://markmail.org/search/?q=list%3Anet.java.dev.jersey.users+brett.dargan%40gmail.com#query:list%3Anet.java.dev.jersey.users%20brett.dargan%40gmail.com+page:1+mid:7ln7wixfihfodngg+state:results
2) For building "lighter" response entities I typically have a BeanLite.class with just the properties I need for a summary and then a Bean.class extending it with more detail. You can add both to your ORM and provide an option to switch representations in your DAO.
Thanks for all your responses. Going through all the approaches you guys presented and after a little bit of research on my own, this is what I settled on:
1) I am adding uri as part of the object model. This seems to be the cleanest solution to me currently. The URI can be automatically populated whenever the object is created (using other properties of the object). Earlier I thought this is a bad idea, but I am not able to foresee any problems with this approach other than the extra field that will have to keep moving with the objects.
2) For supporting full/partial views, I am trying to use the #JsonView annotation. This seems to be a good approach.
Let me know if there are any other potential issues with this way of handling things.

using eclipse template to create test cases

Often do I find myself creating the same unit tests methods to getters\setters, c'tors and Object methods (hashCode, equals and toString).
What I'm trying to achieve, with the help of Eclipse IDE, is automation of this procedure.
consider this example:
public Class Person {
private String id;
private String name;
public Person(String id, String name){
this.id = id;
this.name = name;
}
public String getId() { return id; }
public void setId(String id) {
this.id = id;
}
public String getName() { return name; }
public void setName(String name) {
this.name = name;
}
#override
public int hashCode(){ ... }
public boolean equals(Person other){ ... }
public String toString(){ ... }
/* this class may implement other logic which is irrelevant for the sake of question */
}
The unit test class will look something like this:
public class PersonTest extends TestCase
{
#override
public void setup() {
Person p1 = new Person("1","Dave");
Person p2 = new Person("2","David");
}
#override
public void tearDown() {
Person p1 = null;
Person p2 = null;
}
public void testGetId() {
p1.setId("11");
assertEquals("Incorrect ID: ", "11", p1.getId());
}
public void testGetName() { /* same as above */ }
public void testEquals_NotEquals() { /* verify that differently initialized instances are not equals */ }
public void testEquals_Equals() { /* verify that an object is equals to itself*/ }
public void testHashCode_Valid() { /* verify that an object has the same hashcode as a similar object*/ }
public void testHashCode_NotValid() { /* verify that different objects has different hashcodes*/ }
public void testToString() { /* verify that all properties exist in the output*/ }
}
This skeleton is similar to the vast majority of classes created.
can it be automated with Eclipse?
Have a look at Fast Code. It is an eclipse plugin that provides very nice feature of templating stuff which is what you seem to be looking for. On the documentation page look for Create Unit Test section.
A very useful feature of this plugin is to create unit tests automatically. Unit tests can be of type Junit 3, Junit 4 or TestNG. For Junit 4 or TestNG tests, appropriate annotations will be automatically added. One needs to configure it just once.
Unit tests are meant to show that an Object's behaviour is conforming to it's expected behaviour. They are not meant to make sure that the Java language is working correctly.
What you have here is a fancy data structure, with no behaviour. In that case every assignment is mediated by a method call, and every dereference is also mediated by a method call. Since Object Oriented programming is "data + behaviour" = objects, and this code lacks behaviour, it's a candidate for being called non-object-oriented code.
Sometimes Java uses non-object-oriented classes to facilitate transfer of information. The class guarantees that all information gets transferred as one unit when doing serialization. So having such a class isn't an indicator that the code is wrong; however, if you run into too many classes like this then something is very wrong.
One key element of testing is that it's not really a test if the test cannot fail. If the test cannot fail, it's just busywork. Assuming that one of these fields cannot be null then the setter might look like
public void setName(String name) {
if (name == null) throw new IllegalArgumentException("name cannot be null");
this.name = name;
}
And then you have something to test. Otherwise, your just checking to see if the assignment operator failed. As an aside, if the assignment operator failed, then I'd wager that the JVM is going to come down pretty hard sooner (rather than later) and you can't trust your tests to report correctly either.

Categories