Not strictly necessary, but probably not a bad idea to encourage folks
to at least get on v3.x since it does contain relevant performance
improvements.
Shouldn't be any reason preventing folks from using the latest version
of Encore unless they're on a really ancient version of Clojure
(< v1.7 released 2015).
Before this commit:
(freeze true) => froze as primitive `true`
(freeze false) => froze as primitive `false`
(freeze (Boolean. <anything>)) => froze as primitive `true`
After this commit:
Boxed Booleans are first unboxed to correct primitive value before freezing
This was a long-standing bug, though thankfully unlikely to have affected most
users since boxed Booleans are rarely used in Clojure. Cases with Java interop
are the most likely to have been affected.
A big thanks to Roland Thiolliere (@RolT) for this fix!
Removed 2x vars:
- *serializable-whitelist*
- swap-serializable-whitelist!
Added 4x vars:
- *freeze-serializable-allowlist*
- *thaw-serializable-allowlist*
- swap-freeze-serializable-allowlist!
- swap-thaw-serializable-allowlist!
Deprecated 2x JVM properties:
- taoensso.nippy.serializable-whitelist-base
- taoensso.nippy.serializable-whitelist-add
Deprecated 2x ENV vars:
- TAOENSSO_NIPPY_SERIALIZABLE_WHITELIST_BASE
- TAOENSSO_NIPPY_SERIALIZABLE_WHITELIST_ADD
API is otherwise identical.
MOTIVATION
An API break is unfortunate- but the break here is small, and the
benefit significant.
By separating the freeze/thaw lists, it becomes possible to safely
allow *any* classes to be frozen - and so effectively make the
allowlist a purely thaw-time concern in the common case.
This has several advantages including:
- No risk of Nippy calls unexpectedly throwing where they didn't
before.
- The ability to adjust or bypass the thaw allowlist *after*
seeing which class objects have been quarantined.
In general: this change eases migration to RCE-safe Nippy from
RCE-vulnerable versions. This is especially useful in cases where
Nippy is being used as an ~implementation detail for another
library/application/service.
We have 2 options:
A: Default to Serializable whitelist checks on both freeze and thaw
B: Default to Serializable whitelist checks only on thaw
Before this commit, Nippy was taking option A.
As of this commit, Nippy is taking option B.
Both are equally safe re: the risk of Remote Code Execution in #130:
- Freezing a malicious payload is *not* a security risk
- Thawing a frozen malicious payload *is* a security risk.
But option B has the benefit of not throwing exceptions by default
against a whitelist that has not [yet] been properly configured.
This is especially helpful for other libraries or applications that
may be using Nippy as an underlying dependency.
Behaviour under our two options against a whitelist that has not
[yet] been properly configured:
A: Throw exception on freeze
B: Freeze successfully, and thaw successully as
{:nippy/unthawable {:class-name <> :content <quarantined-ba> :cause :quarantined}}
I think this is probably less of a nuissance, and so a better default.