I need to ensure that the application I am writing has no Jackson XML/JSON vulnerabilities (CSV's). All the discussions I have seen talk about how to manage it! I want it OFF.
I am using the latest Jackson version 2.10.0 and the latest Spring boot 2.1.9 and Spring 5.2.0 but I have to justify my use of Jackson and I do not require any polymorphic behaviour.
The doc says I need to use activateDefaultTyping(). This sounds as if it turns it ON. Do I need to use activateDefaultTyping and implement PolymorphicTypeValidator to prevent it? Do I need this to prevent ALL polymorphic behaviour?
I have read lots of articles on managing the behaviour but I am still unclear what the default behaviour is. If it is polymorphic by default I need to turn if OFF.
You are vulnerable if you accept input from third parties, outside your application, in JSON format through your external API, and in which input you accept fields of type Object (or other widely implemented classes like Serializable). Then a potential attacker could send (almost) anything, including widely available classes (so called gadget classes), available on your classpath, whose constructors or setters execution (upon instantiation by Jackson at deserialization time) could result in dangerous effects on your system.
In order to be vulnerable, you need to have your Object field annotated with
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "#class", visible = true)
or use
ObjectMapper.enableDefaultTyping()
or
ObjectMapper.activateDefaultTyping() from Jackson 2.10.0
This will tell Jackson to deserialize the incoming json into the specific type specified by #class.
Otherwise, whatever data is sent will be deserialized into a key-value map by default.
So by default the "default typing" is OFF.
The activateDefaultTyping() you've mentioned should be used only in to be used in combination with a custom validator to define yourself in a decoupled way what types you allow for deserialization.
In shortest: if you want it OFF and don't need polymorphic deserialization, don't use #JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) or don't enable it specifically.
You can also call
ObjectMapper.deactivateDefaultTyping() to be sure it's not used, but note that using #JsonTypeInfo on your classes will not be affected by this call.
Related
I am providing the ability to deserialize a list of entities returned from JPA, however the list type returned from JPA is DelegatingResultList which has no default constructor.
The implementation uses proxy beans with AOP where I intercept interfaces that extend a set of interfaces to provide basic queries.
I can easily fix this by checking in my aspect if the object type is DelegatingResultList and then copy to an ArrayList, but I don't want to have to do this for every single aspect that I'm covering.
I am using the default typing to set as a property like so:
objectMapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
The json in the serialized format with my value wrapper looks like this:
{"#class":"my.wrapper.ValueWrapper",
"response": ["org.apache.openjpa.kernel.DelegatingResultList",
[{"#class":"my.entity.TaxInfoEntity","taxType":"01","taxVal":"0.07"}, ..."]]"}
I have read about using mixins and custom deserializers, but everything I've tried doesn't seem to work.
I have tried using a Mixin, but I have no reference to the ResultList property as it's not saved in the json. Not to mention it doesn't even kick in when it's trying to deserialize.
I have tried using a custom deserializer but again, this never kicks in when deserializing. Would I be correct in assuming the mixin and custom deserializer only kick in if you try to deserialize passing the class as the type?
This of course would be read only as it's a cached value. So my intention is to convert to an Arraylist instead. How would I achieve this using Jackson?
I am using https://immutables.github.io/ library with Jackson.
I want my class to be Jackson-serializable. I would like to use custom PropertyNamingStrategy (configured for com.fasterxml.jackson.databind.ObjectMapper using mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
Unfortunately Immutables library puts #JsonProperty("propertyName") at every field in generated code. That overrides PropertyNamingStrategy defined at mapper level (or at class level, using #com.fasterxml.jackson.databind.annotation.JsonNaming annotation).
Is it possible to make Immutables library stop putting property name for every field (using org.immutables.value.Value.Style or similar means)?
I have come with workaround, putting #JsonProperty (without value) at every property, but I am not satisfied with this.
Style property forceJacksonPropertyNames=false does not force property names to specific strings. It works with naming strategies configured at class level and at mapper level.
Introduction to styles is available here: http://immutables.github.io/style.html
You can read some background information about this setting in issues: https://github.com/immutables/immutables/issues/431 https://github.com/immutables/immutables/issues/353
I have a requirement to receive JSON with keys that contain underscore and even ignore the case in words. For e.g. Device_control_API, device_control_API, Device_Control_API, device_control_aPI etc all should map to same property.
Now I know that I can create multiple setter methods using #JsonSetter with all combinations possible, but I don't think that will be good.
I have seen other questions which suggest using mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
for ObjectMapper object to ignore case, but I can't do that because I am using spring-boot and want my REST API to get payload in the form POJO object.
Is there any annotation or some way to do so
Please help !!!
I dont think you can use the MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES as annotation. Got the following information from here
Jackson on/off features: MapperFeature
Jackson defines a set of per-mapper configuration, which can ONLY be
defined before using ObjectMapper -- meaning that these settings can
not be changed on-the-fly, on per-request basis. They configure
fundamental POJO introspection details, and resulting built objects
(serializers, deserializers, related) are heavily cached. If you need
differing settings for these, you have to use separate ObjectMapper
instances.
And the MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES is one of the configuration.
But maybe a custom deserialization class could help you. There are many tutorials and questions on Stackoverflow.
I found some:
Jackson: using #JsonSerialize (or #JsonDeserialize) annotation to register a custom serializer (or deserializer)
Right way to write JSON deserializer in Spring or extend it
There is also this property:
spring.jackson.mapper.accept_case_insensitive_properties=true
Following my previous question about serialization only, I'd like to go further and support JsonFormatVisitor.
I have the same requirements, that is:
I have objects of several types (interfaces).
I don't know the type of theses objets in advance.
I can't add annotations on theses types.
I can introspect all theses objets to get their state data.
Now that serialization works, I need to generate JsonSchema and hence do something like that:
SchemaFactoryWrapper visitor = WHAT?
mapper.acceptJsonFormatVisitor( mapper.constructType( Foo.class ), visitor );
JsonSchema jsonSchema = visitor.finalSchema();
String schemaString = mapper.writeValueAsString( jsonSchema );
I've implemented a SchemaFactoryWrapper that gets its expectAnyFormat called but I don't know what to do inside it. Looks like there's no schema for "any" objects.
Maybe I can hook elsewhere in jackson? Maybe it is possible to extends the whole Bean/Property introspection mechanism to support a completely different model (ie. not beans)?
I'm a bit lost, please help me find the treasure room :)
I can try to suggest some approaches that may be helpful.
First, even if you can not annotate classes directly, "mix-in annotations" can help -- this does assume static knowledge, however
Second, since schema-generation uses type detection used for serialization, you may want to register custom serializers; but this does not necessarily mean having to hand-write all. The most flexible way to register custom serializers is via Module interface (mapper.registerModule(new MyModule()); Modules can register Serializers instance which gets called when trying to locate a JsonSerializer for a type for the first time (after this, instance is cached to be re-used for other properties of same type).
This is where you could configure and return your custom JsonSerializer; but it might only need to handle schema-related callback(s) (one(s) called by schema generator).
It is also possible to extend/modify property discovery mechanism; whether this is easier depends. But the thing to look for is registering BeanSerializerModifier via Module.
It gets called during construction of BeanSerializer (general POJO serializer used unless something more specific is registered), and with it you can add/modify properties; or just replace resulting serializer altogether (and also then allows chaining of custom serializer with default one, if needed).
Need to serialize java objects to JSON while doing compression such as name change, exclusion etc. Objects use class from jar, source code of which is not available.
Looked through many libraries(Jackson , Gson), but found none solving this particular problem. Most of them are annotations based, which I can't use given I don't have source code.
One way to solve this problems is, use reflection and recursively go through object until you find a property name of which should be replaced or object is excluded in serialized JSON.
Need solution for this. Better if it is already implemented and tested.
You can also have a look at Genson library http://code.google.com/p/genson/.
You can rename and filter with quite concise code:
// renames all "fieldOfName" to "toName", excludes from serialization
// and deserialization fields named "fieldNamed" and declared in DefinedInClass
// and uses fields with all visibility (protected, private, etc)
Genson genson = new Genson.Builder().rename("fieldOfName", "toName")
.exclude("fieldNamed", DefinedInClass.class)
.setFieldFilter(VisibilityFilter.ALL)
.create();
genson.serialize(myObject);
If you want to do some more complex filtering (based on annotations for example) you can implement BeanMutatorAccessorResolver or extend BaseResolver.
Same for property renaming you can implement PropertyNameResolver and have full control.
And finally if you want to filter fields, methods or constructors according to their modifiers you can define your own VisiblityFilter.
Concerning performances of filtering/renaming there should be no problem as it is done only once per class and then cached.
To start using Genson you can have a look at the Getting Started Guide.
Found solution to the problem.
Google gson has class called GsonBuilder which has methods for exclusion strategy and naming strategy.
Using these two methods implemented a custom solution, where all the mapping and exclusion rules are stored using a xml and used at the time of serialization and de-serialization.
Works perfectly, though not sure about the performance of same.