-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow handling of single-arg constructor as property based by default #1498
Comments
I still have big misgivings on this helping some users and hurting others; mostly for cases where constructor with But! With 3.0 planning, I think this is reasonable thing to do. Support for JDK datatypes that rely on delegation will need to be handled separately, but I also don't know how many such types are left. |
Since there are users that rely on this feature a feature flag should also be provided. |
+1 I think it should be the default behavior in 3.x. |
Yet no one has explained how to protect against very likely case of accidental discovery of constructor that are not meant to be used as creators. In fact this would likely open a new attack vector in case of polymorphic deserialization, as constructors of JDK/3rd-party libraries that were not previously considered will now be discovered. With Jackson 3, new discovery mechanism needs to be defined (not just or mainly for this issue), and we can and should tackle this. But I have concerns about how far we can get with zero annotations. |
@cowtowncoder do you have a valid use case for a constructor not meant to be used as creator ? |
@cowtowncoder, what does it mean accidental discovery of constructor? I don't see a case where that would happen because we always know the type we want jackson to deserialize and it's either our own classes or JDK ones. JDK ones aren't compiled with '-parameters'. |
@sylvainlecoy About any class that has not been primarily created for use as json POJO, such as JDK types. I am not worried about ones designed for use, but (especially for security reasons) ones that are not -- with polymorphic typing it is possible in some cases to exploit methods/constructors/fields in clever ways. @lpandzic Ok, good info wrt JDK parameter names (or lack thereof). You may have mentioned it earlier but I keep forgetting. Other than that:
I will need to create issues at: https://github.com/FasterXML/jackson3-dev to kick start design discussions on mailing list: this will need to occur after |
@lpandzic forgot one other thing: even if JDK types do not have parameter names (which is good here), 3rd party libraries probably would. A good document of problems is this: https://github.com/mbechler/marshalsec/blob/master/marshalsec.pdf which outlines existing security problems: expansion here could allow more constructors as potential attack vectors (esp. if it'd be for any number of parameters, not just one). Note that this specifically relates to polymorphic deserialization, in which attacker specifies class name of class to use -- in which case all they have to do is to fine suitable attack vector. It is difficult to really gauge potential for abuse here since I do not think many Java deserializers allow detection of such constructors (and since parameter name inclusion is still relatively new feature for bytecode). But absence of known cases at this point does not prove, in my opinion, that there are none. Rather that we simply do not know, but that there is good reason to suspect there are constructors that would be problematic, within widely used 3rd party libraries. This is still different, of course, from my earlier objection of mismatched constructors. |
@cowtowncoder I understand your point, but is this a blocker for this feature? Considering default constructors and setters vs constructor I'm not sure why it would make much of a difference for an attacker? Don't you have to specify for polymorphic classes all instances of hierarchy on parent class and don't you always have to specify parent target in your code for deserialization? If target is ever concluded from serialized format (json) then that is the cause of security risks as you can program through serialized format and that is not good security wise. If I want to deserialize library class and that library is compromised, there is no rescue. |
@cowtowncoder any update on this? |
Hi there, any chances to see that landing one day ? |
@sylvainlecoy In some form, yes. Either by letting users configure default, or, perhaps, by allowing both bindings. But I do not have timeline for this. 2.11.0 is being finalized and I doubt I have time to tackle this for that. |
@cowtowncoder thanks for the quick reply. I am currently using @JsonCreator to fix this issue but I don’t like the idea having to put an annotation for these classes as the rest works flawlessly without the need of annotation. Did I missed a configuration property which could help me avoid having to put such annotations or using MixIns ? Thanks for your time. |
@sylvainlecoy No, unfortunately there is no such option. However, you can make it work in the meantime for your case by overriding this method:
in |
That worked perfectly for my use case thanks |
@cowtowncoder I just noticed the most wanted tag. Any reason why this issue is not on that list? |
@lpandzic Only because I just added the label and have added whenever encountering one. This definitely warrants one-- thank you for update. I know I have promised to tackle this "real soon now" for a while. But with caveat of this sorry history, I do plan to have another look with 2.12, having some new ideas. |
Was about to add a simple setting ("defaultCreatorMode" of type It seems pointless to add a new configuration option that does not solve the main problem, but I think there is one possible case if would cover: legacy code that does not use |
On 2.12 work wrt introspection: this would likely mean addition of an Enum that defines aspects of introspection for un-annotated constructors; configuration using "config overrides" style which allows for at least defaults, but also with some work per-type different definition. The main question is that of options to use. But some constraints first:
With that, here are some possibilities:
but I assume other cases might make sense -- I did not consider possibility of what to do if parameter names are not found (quietly ignore otherwise valid candidate, or throw exception?), for example. @lpandzic What do you think? Thank you for all your work, feedback; I know it has been a frustrating journey. |
I think it's a good approach but I wouldn't dwell on it. For 0 arg constructor case or more constructors present - use the default behavior we had until now. I don't see any value in solving or rethinking that part really, especially after introduction of records. So for me, jackson should handle javabean and record style of data holders out of the box and for everything else you have options that you can take but with a cost - it's not out of the box but certain effort is required like annotations or something else. No problem, I'm glad I can help make java ecosystem a little bit more robust and user friendly :) |
Finally finding time to work on this, possibly the last "must-have"/most-wanted feature for 2.12.
With this, pre-configured instances would be:
The real power would probably come from |
Work here progressing, and now the original case passes when mapper is constructed like so:
I realized that implementing
Of these I implemented the bigger piece (1) and need to add (2) and (3). |
To anyone that can't upgrade jackson you might want to try this module - https://github.com/infobip/infobip-jackson-extension#SingleArgumentPropertyCreatorAnnotationlessSupport.
Here's a test that probably speaks better for itself what is supported - https://github.com/infobip/infobip-jackson-extension/blob/master/infobip-jackson-extension-module/src/test/java/com/infobip/jackson/SingleArgumentPropertiesCreatorModeAnnotationIntrospectorTest.java. |
With the parameter-names-module enabled I'd expect this class to be correctly deserialized from
{"bar":{...}}
.More than once have users hit this issue and asked why isn't it handled this way (#1135, #8, #21).
It might also be a good idea to provide an option to change this behavior (HANDLE_SINGLE_ARG_CONSTRUCTOR_AS_PROPERTY_CREATOR).
The text was updated successfully, but these errors were encountered: