在 2018年10月17日星期三 UTC+8上午12:54:52,Tatu Saloranta写道:
>
> On Tue, Oct 16, 2018 at 9:50 AM wjm wjm <[email protected] <javascript:>>
> wrote:
>
>>
>> 1/2. "too big" or "too small" number, maybe should throw exception, just
>> like Integer.parseInt(......);
>>
>
> yes, in cases where this occurs that makes sense.
>
>
>> 3.valid range of BigInteger/BigDecimal should be determined by different
>> scenes
>> but i'm not sure what is the "best" default configuration
>> or just default to unlimit, it's develop team's duty to set a valid
>> configuration for it, :)
>>
>
> The problem here is that if there is anywhere someone with legitimate use
> and that breaks in a patch release,
> dev team usually gets to hear about it. So it is important to balance
> quick fix with some caution.
>
my "develop team" means customer team, not jackson team, so default to
unlimit will not break customer's logic
but if they want to fix DoS attack problem of BigInteger/BigDecimal (not
enum/int/long and so on), they must set a sensible range for their
business logic.
>
> But I think that one relative small fix to `_parseSlowInt()` (which I
> checked in 2.9 branch)
> might help quite a bit, if anyone wants to test. I will try to add tests
> too, but this is tricky one
> to test... not sure how to automate since it is very difficult to
> automatically verify timing
> problems due to usual performance measurement challenges (JVM startup
> slowness etc).
>
> -+ Tatu +-
>
As long as the numbers are large enough, then old parse speed is very slow
eg:
Strings.repeat("1", 100_0000)
old logic will cost 17+ seconds in my machine
but if fail quickly, only cost 10+ milliseconds
so think about difference between machines, we can treat less than 1
second to be a fixed status?
>
>
>>
>> 在 2018年10月16日星期二 UTC+8下午11:08:11,Tatu Saloranta写道:
>>>
>>> On Tue, Oct 16, 2018 at 8:02 AM wjm wjm <[email protected]> wrote:
>>> >
>>> > seems that jackson have some problems when parse super number
>>> > Gson failed at once, but jackson block long times and then failed
>>> > because jackson parse the super number to BigInteger first and then
>>> convert to target number type.
>>> >
>>> > i write a reproduce test case
>>> > please help me to resolve the problem, thanks
>>> >
>>> > package test.jackson;
>>> >
>>> > import java.util.concurrent.Callable;
>>> >
>>> > import com.fasterxml.jackson.databind.ObjectMapper;
>>> > import com.google.common.base.Strings;
>>> > import com.google.gson.Gson;
>>> > import com.google.gson.GsonBuilder;
>>> >
>>> > public class DoS {
>>> > static String input = Strings.repeat("1", 100_0000);
>>> >
>>> > static Gson gson = new GsonBuilder().create();
>>> >
>>> > static ObjectMapper mapper = new ObjectMapper();
>>> >
>>> > public static enum Color {
>>> > WHITE,
>>> > BLACK
>>> > }
>>> >
>>> > static void run(String name, Callable callable) {
>>> > System.out.println(name);
>>> >
>>> > long start = System.currentTimeMillis();
>>> > try {
>>> > Object result = callable.call();
>>> > System.out.println(" result:" + result);
>>> > } catch (Throwable e) {
>>> > //System.out.println(" failed: " + e.getMessage());
>>> > System.out.println(" failed");
>>> > }
>>> > System.out.println(" time:" + (System.currentTimeMillis() -
>>> start) + " ms");
>>> > }
>>> >
>>> > public static void main(String[] args) {
>>> > run("Gson enum:", () -> gson.fromJson(input, Color.class));
>>> > run("Jackson enum:", () -> mapper.readValue(input, Color.class));
>>> > System.out.println();
>>> >
>>> > // byte/Byte/short/Short/int/Integer/long/Long
>>> > // all these types, jackson is very slow
>>> > run("Gson int:", () -> gson.fromJson(input, int.class));
>>> > run("Jackson int:", () -> mapper.readValue(input, int.class));
>>> > System.out.println();
>>> >
>>> > // float/Float/double/Double
>>> > // all these types, jackson is very slow
>>> > run("Gson double:", () -> gson.fromJson(input, double.class));
>>> > run("Jackson double:", () -> mapper.readValue(input,
>>> double.class));
>>> > System.out.println();
>>> > }
>>> > }
>>> >
>>> >
>>> > the output is :
>>> > Gson enum:
>>> > result:null
>>> > time:16 ms
>>> > Jackson enum:
>>> > failed
>>> > time:17469 ms
>>> >
>>> > Gson int:
>>> > failed
>>> > time:32 ms
>>> > Jackson int:
>>> > failed
>>> > time:17392 ms
>>> >
>>> > Gson double:
>>> > result:Infinity
>>> > time:8 ms
>>> > Jackson double:
>>> > result:Infinity
>>> > time:18187 ms
>>>
>>> Ok, this is obviously a big problem. I filed:
>>>
>>> https://github.com/FasterXML/jackson-databind/issues/2157
>>>
>>> to cover it, and this is related to earlier
>>>
>>> https://github.com/FasterXML/jackson-databind/issues/2141
>>>
>>> Unfortunately problem is difficult to tackle. Jackson does figure out
>>> magnitude part during decoding, and use "smallest possible" type
>>> for integral numbers, from group of `int`, `long` and `BigInteger`
>>> (for floating-point logic is bit different, but similar idea applies).
>>> Problem occurs when target type needed by databinding is something
>>> else: like very long integer number that is to be used for filling
>>> `int` field. This operation is slow with JDK, and should be avoided
>>> partly because overflow check would fail anyway -- but this is only
>>> applied after very slow conversion, allowing DoS attacks.
>>>
>>> I have some questions on how this could and should be handled,
>>> regarding things like:
>>>
>>> 1. On "too big" (big magnitude) number, should we typically truncate
>>> to MAX_VALUE (for `double`), or throw exception (latter for integral I
>>> think)
>>> 2. On "too small" (small magnitude) number, should we truncate to zero
>>> 3. If applying strict limits to longest BigInteger/BigDecimal, are
>>> there safe length limits? Same use cases (like cryptography) use
>>> relatively long numbers legitimately, for example
>>>
>>> But. Maybe I can figure out solution to bounds-check-fail case at least,
>>> first.
>>>
>>> -+ Tatu +-
>>>
>>> ps. This is not limited to json either; almost certainly applicable to
>>> XML, YAML, possibly CSV, Properties. So I think help would be useful
>>> in figuring out extent of the problem.
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "jackson-user" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected] <javascript:>.
>> To post to this group, send email to [email protected]
>> <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
--
You received this message because you are subscribed to the Google Groups
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.