Skip to content
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

OOM on some BigDecimal inputs during serialization #29

Open
migesok opened this issue Nov 6, 2018 · 5 comments
Open

OOM on some BigDecimal inputs during serialization #29

migesok opened this issue Nov 6, 2018 · 5 comments
Labels

Comments

@migesok
Copy link
Contributor

migesok commented Nov 6, 2018

For a serializer generated for a case class which contains a BigDecimal field, if a number with sufficiently big scale supplied (like BigDecimal("3E1000000000")), serialization logic blows in memory causing OOM.
This could be a possible source for DoS attacks.

@migesok migesok added the bug label Nov 6, 2018
@plokhotnyuk
Copy link
Contributor

plokhotnyuk commented Nov 6, 2018

It seems that using of toPlainString wasn't the best idea:

q"output.writeString($arg.underlying.toPlainString)"

But even in case of using of toString users can be affected after parsing of such values. Just try to pass the parsed value of that big decimal number to the following function and see what will happen:

scala> val f = (x: BigDecimal) => x + 1
f: BigDecimal => scala.math.BigDecimal = $$Lambda$1210/93981118@790ac3e0

So, we should avoid returning of parsed BigDecimal with too big exponent or with MathContext.UNLIMITED.

As example to mitigate possible DoS attacks jsoniter-scala uses safe defaults that limit a scale value and number of significant digits. Also, it sets MathContext.DECIMAL128 by default:

https://github.com/plokhotnyuk/jsoniter-scala/blob/41573be3df9df4a6f9d29c8b5931cec0c951c7ce/jsoniter-scala-macros/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala#L65-L67

@migesok
Copy link
Contributor Author

migesok commented Nov 6, 2018

@plokhotnyuk I think safe or unsafe to use is out of scope for a serializer. I believe any valid value of any supported type should be reversely serializable without loosing data, that is:

deserialize(serialize a) shouldEqual a

Using toString solves this issue, also the change is perfectly format-backward-compatible.

@t3hnar
Copy link
Contributor

t3hnar commented Nov 7, 2018

@migesok so will there be a pull request ? :)

@plokhotnyuk
Copy link
Contributor

plokhotnyuk commented Jul 1, 2019

@t3hnar what about changing the representation from textual to binary?

As example, will it be acceptable if BigDecimal values be serialized as byte arrays of mantissas followed by int of scale?

In any case, the value of MathContext and a limit for scale can be configured by some system property or by introducing some configuration parameters for the macros, isn't it?

@t3hnar
Copy link
Contributor

t3hnar commented Jul 1, 2019

@plokhotnyuk why not? it is a binary format at the end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants