Mass Assignment: Insecure Binder Configuration with Fortify Java 1.8 EJB - java

I am trying to solve some vulnerabilities issues, and I have one that I couldn't solve it, I tried to add #Valid annotation in sync method but same error, this is the description from fortify:
The framework binder used for binding the HTTP request parameters to
the model class has not been explicitly configured to allow, or
disallow certain attributes.
To ease development and increase productivity, most modern frameworks
allow an object to be automatically instantiated and populated with
the HTTP request parameters whose names match an attribute of the
class to be bound. Automatic instantiation and population of objects
speeds up development, but can lead to serious problems if implemented
without caution. Any attribute in the bound classes, or nested
classes, will be automatically bound to the HTTP request parameters.
Therefore, malicious users will be able to assign a value to any
attribute in bound or nested classes, even if they are not exposed to
the client through web forms or API contracts.
The error I am getting in this line:
public ResponseClass sync(#BeanParam MyClassRequest request) throws
Exception {
MyClassResource.java
#Api(tags = "Relay")
#Stateless
public class MyClassResource extends AbstractService<MyClassRequest, ResponseClass> {
#EJB
private MyClassService myClassService;
#POST
#Path("/api/v1/service")
#Produces({"application/json"})
#ApiOperation(value = "Processes Conn",
response = ResponseClass.class, responseContainer = "ResponseClass", hidden = true)
#Override
public ResponseClass sync(#BeanParam MyClassRequest request) throws Exception {
myClassService.processFeed(request);
return new RelayResponse(HttpStatuses.ACCEPTED.getStatus());
}
MyClassRequest.java
In this file I have tried #FormParam("ccc") but same
public class MyClassRequest extends RelayRequest {
public MyClassRequest() {
super.setMessageType("not required");
}
private String myData;
private String conneRid;
private String connectionCreatedDate;
If someone could give some hint that how I can solve it, I will really appreciate it.

Do you expect all fields to be present in request? You are using #Valid annotation but there are no validation annotations in MyClassRequest model. Try to add some validation annotations like #JsonIgnore for non mandatory fields. Or #JsonInclude on class. If this does not help, may be also try explicitly adding #JsonProperty on each field.

Related

Concurrent bean validation of container objects (e.g. List)

Context:
Microservice that has exposed REST API and handles input requests in JSON format sequentially. Handled request is deserialized, validated and put into Kafka topic for futher processing.
Given example of class to be validated:
// autogenerated from openapi schema using custom templates
public class DataPayload {
#NotNull
#Size(min=1, max=100)
private String description;
#Valid
#Size(max=1024)
private List<DataLine> dataLines;
// getters, setters, etc.
public static class DataLine {
// lots of fields to be validated..
}
}
We run validation using jsr303/jsr380 Bean Validation:
public static void main(String[] args) {
var validator = Validation.buildDefaultValidatorFactory().getValidator();
var violations = validator.validate(getDataPayload());
}
Does anybody have an idea how validation of List<DataLine> dataLines could be parallelized with minimal efforts?
Several (obvious) options I have so far:
Manually run in parallel validator.validate(dataLine) from the list along with validation DataPayload without dataLines validator.validate(withoutDataLines(dataPayload)).
Similar to 1st option but with some tricks around Validation Groups.
(Not sure if it is possible). Custom ConstraintValidator that runs validation for container objects in parallel. Open question - how to delegate nested/cascaded validation to default mechanism?
Despite options are viable I am wondering is there more smart and elegant way to solve this problem..

What's the cleanest way to differientiate identical serialized objects?

I've got two root exception types my service is throwing
class ServiceException extends RuntimeException {
private Status status;
private String someString;
// Boilerplate omitted
}
class RetryableServiceException extends ServiceException {
// This class has no new fields
}
Because there's a common retry framework our clients will use which determines whether to retry or not based on the exception class.
But the problem, obviously, is that when the client gets the response and calls Response.readEntity(Class <T> entityType) they will just get an instance of whatever class they're trying to read, since they have the same fields.
Clearly I need to add some other field which distinguishes these two objects, but how can I add that to the builders and constructors in a way that:
Doesn't require a ton of client logic,
doesn't needlessly complicate the exception objects, and
can be understood by Jackson?
To answer your main issue, You don't want to couple the clients and the server so tightly by having the clients use the same exact Exception classes used on the server, create a generic error bean and map exceptions to that bean then serialise/de-serialise it. You can do that in a transparent way using javax.ws.rs.ext.ExceptionMapper, this error bean can have canRetry or shouldRetry fields. An example implementation
public class RetryableServiceExceptionMapper implements ExceptionMapper<RetryableServiceException> {
#Context
Request request;
public Response toResponse(RetryableServiceException exception) {
ApiError error = ApiError.builder().canRetry(true).message(exception.getMessage()).build();
return Response.status(status).cacheControl(cacheControl).tag(eTag).entity(error).type(APPLICATION_XML);;
}
}

Injection of stateless session bean into custom JsonDeserializer fails

I am building an application providing a JAX-RS REST service using JPA (EclipseLink). When exposing User entities over JSON, I am using the #XmlTransient annotation on some fields (e.g. the password field) to hide them from the JSON representation. When sending a create or update (POST/PUT) operation, I would like to populate the missing fields again so JPA will correctly perform the operation.
My current approach is that I have a custom JsonDeserializer that is used to deserialize the User and to add the missing fields. For this I would like to inject (using #Inject) a UserFacadeREST bean which handles the JPA-stuff. However, this injection fails and the bean instance is null (which then of course causes a NullPointerException).
My UserFacadeREST bean is annoted as follows:
#Stateless
#LocalBean
#Path(UserFacadeREST.PATH)
public class UserFacadeREST extends AbstractFacade<User> {
//...
}
My UserDeserilizer (custom JsonDeserializer):
public class UserDeserializer extends JsonDeserializer<User> {
#Inject
private UserFacadeREST userFacade;
#Override
public User deserialize(JsonParser parser, DeserializationContext context) throws IOException,
JsonProcessingException {
JsonNode node = parser.getCodec().readTree(parser);
int userId = (Integer) ((IntNode) node.get("userID")).numberValue();
System.out.println(userId);
User user = userFacade.find(userId); // This line produces the NullPointerException
return user;
}
}
which I then use on my User entity with #JsonDeserialize:
#Entity
#Table(name = "User")
#XmlRootElement
#JsonDeserialize(using = UserDeserializer.class)
public class User implements Serializable {
// ...
}
I have included a bean.xml file in my WEB-INF folder with bean-discovery-mode set to all. What am I missing?
Jon Peterson pointed me to the right direction. I finally chose to implement the 'hackish' solution, in a way. Please note that there are basically 2 options here (if you know another one, please let me know!). Short version:
Hackish solution (the solution I chose): inject a bean programmatically using javax.enterprise.inject.spi.CDI.current().select(UserFacadeRest.class).get() as described in the accepted answer of the question mentioned by Jon or
Better (clean) solution (but also more elaborate): Redesign the logic to fill the missing fields after deserialization as suggested by Jon.
So for my question, the solution looks as follows:
1.
import javax.enterprise.inject.spi.CDI;
public class UserDeserializer extends JsonDeserializer<User> {
private final UserFacadeREST userFacade =
CDI.current().select(UserFacadeREST.class).get();
// Rest as before
}
2. In this case, in the deserialize method of my JsonDeserializer I would construct a User that just holds the userID. In every request method I would then have to examine all the users and replace them by the actual user by calling EntityManager.find(User.class, user.getUserID()). This means more effort in the business logic as you have to keep in mind that everytime you need to work on a User in a request method, you first have to do a query to get the 'full' User object. In the first solution, this query is hidden from the business logic and already happens in the JsonDeserializer.
public class UserDeserializer extends JsonDeserializer<User> {
#Override
public User deserialize(JsonParser parser, DeserializationContext context) throws IOException,
JsonProcessingException {
JsonNode node = parser.getCodec().readTree(parser);
int userId = (Integer) ((IntNode) node.get("userID")).numberValue();
return new User(userId); // Placeholder User object containing only the user ID, needs to be replaced in business logic
}
}
I'm not super familiar with CDI, but some quick Google'ing leads me to believe that bean-discovery-mode should either be all, annotated, or none (true not being a valid value). Reference
If that doesn't fix it, it might be the same issue that Spring would have: you have to declare your UserDeserializer as a bean for the dependency injection to be applied.
EDIT: Just found this other question that is basically the same issue you are having.
Ultimately, you probably need to just redesign the logic to call userFacade after deserialization.

How is Errai able to serialize/deserialize model entities

I'm trying to use Errai rest capabilities in my GWT app,
I took a look at the following guide:
http://errai-blog.blogspot.it/2011/10/jax-rs-in-gwt-with-errai.html
In particular, it says:
We simply put this interface somewhere in our client packages (e.g.
client.shared) where the GWT compiler can find it. To create a request
all that needs to be done is to invoke RestClient.create()
I think there's a plot hole here, how is Errai able to know how serialize/deserialize model classes ?
Can you help understanfing this ?
thanks
According to RestClient Class's create() method
public static <T, R> T create(final Class<T> remoteService, final RemoteCallback<R> callback, Integer... successCodes) {
return create(remoteService, null, callback, null, successCodes);
}
In example which you've provided; when using create() method Errai gets the CustomerService Class as remoteService, After many operations;
Errai parses and implements this CustomerService Interface with using their errai-codegen library which uses Java Reflection API.
When parsing simply;
First it looks for JAX-RS annotated methods and defines them as
JaxrsResourceMethod
Then it looks into parameters of that method if there is any parameter that annontated with JAX-RS annotations.
If it finds annontated parameters in JaxrsResourceMethod, it keeps that parameter with it's annotation type
If it finds not annontated parameter in JaxrsResourceMethod it defines as a entityParameter
Errai holds these annotated parameter and entityParameters in JaxrsResourceMethodParameters by their method. When building request it uses parameters by their rule.
Let me explain these rules with using an example you've provided.
Customer customer = new Customer("new name", "new last name", "new postal code");
RestClient.create(CustomerService.class, callback).updateCustomer(240193, customer);
Errai will create url like
example.com/cusomers/240193
Because #PathParam("id") annotation rule is adding parameter to the url and according to Errai's entityParameter rule customer will be marshalled when sending data with PUT.
#PUT
#Path("/{id}")
#Consumes("application/json")
#Produces("application/json")
public Customer updateCustomer(#PathParam("id") long id, Customer customer); //- See more at: http://errai-blog.blogspot.com.tr/2011/10/jax-rs-in-gwt-with-errai.html#sthash.2GTQtIg8.dpuf
One more additional note if you check here there is an exception in setEntityParameter method;
Only one non-annotated entity parameter allowed per method:
This means you cant define methods with more than 1 non-annotated parameter in Class which you sent in Errai.

How to retrieve the values from the service which is returning List<Object> using jax-ws

I have a service which returns the List, this object varies depends on different scenario.
Can somebody suggest me does jax-ws support this behaviour or do we have any alternative option.
Since that JAX-WS use JAXB for serializate the objects, JAXB need to know the name of the type for marshall or unmarshall. In a standalone environment can deal with this kind of things. However, when dealing with a list of objects, this becomes more complicated.
Moreover, each data type must be defined in the WSDL. The service client must be able to convert the response XML to the data type desired.
If you wish to return different lists of different type, the simplest is to use a wrapper for the response. e.g.
public class ResponseWrapper {
private List<Audio> audios;
private List<Video> videos;
// setters and getters
}
#WebService
public class MediaStore {
#Inject
AudioService audioService;
#Inject
VideoService videoService;
#WebMethod
public ResponseWrapper getCollections(String artistId) {
ResponseWrapper response = new ResponseWrapper();
response.setAudios(audioService.getAudios(artistId));
response.setAudios(videoService.getVideos(artistId));
return response;
}
}
Another way would be to work directly with SOAP messages, but you could avoid doing so.

Categories