Commit graph

335 commits

Author SHA1 Message Date
Peter Taoussanis
621f1189c7 [nop] Misc housekeeping 2023-08-02 13:43:47 +02:00
Peter Taoussanis
129ce952bc [new] [#151] [#140] Add experimental public-types-spec 2023-08-02 13:29:27 +02:00
Peter Taoussanis
3ac06b6c87 [new] Refactor tools ns, embed dynamic *freeze-opts* in wrappers 2023-08-02 13:28:20 +02:00
Peter Taoussanis
b10a0bf653 [nop] Clean up stress-data 2022-07-01 10:10:54 +02:00
Peter Taoussanis
a362398ccd [#145] [Fix] Freezing custom types with munged field names 2022-06-27 10:38:16 +02:00
Peter Taoussanis
049197072c stress-data housekeeping 2022-06-27 09:59:59 +02:00
Peter Taoussanis
761fcac4df [Change] Improve tools ns docstrings 2022-06-23 13:15:58 +02:00
Peter Taoussanis
9e69a284e1 [#148] [Fix] tools/freeze should use *freeze-opts* even for unwrapped vals 2022-06-23 13:07:02 +02:00
Erik Assum
a2bb1d3de4 [#144] [New] Add org.joda.time.DateTime to default-thaw-serializable-allowlist (@slipset) 2022-06-23 12:35:47 +02:00
Peter Taoussanis
65a138e27c Update Encore memoize (memoize_ was deprecated) 2022-06-23 12:35:47 +02:00
Peter Taoussanis
c9d2aae85d Bump minimum Encore version -> latest
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).
2022-06-23 12:34:48 +02:00
Peter Taoussanis
8909a32bdd [#89 #150] [Fix] Boxed Booleans incorrectly freezing to primitive true (@RolT)
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!
2022-06-23 12:24:40 +02:00
Daniel Mason
8429814a65 [#138] Fix typo bug: medium keyword+symbol length fields should be a Short (@danmason)
Looks like a typo snuck in here and wasn't caught by tests since they didn't include
names >127 characters.
2020-11-18 11:51:34 +01:00
Peter Taoussanis
97dd98ed43 Add default Serializable support for many standard java.time classes
Further additions welcome
2020-11-06 15:50:58 +01:00
Peter Taoussanis
043b37211d Add native support for java.time.Period 2020-11-06 15:50:58 +01:00
Peter Taoussanis
6dd21e0e15 Add native support for java.time.Duration 2020-11-06 15:50:58 +01:00
Peter Taoussanis
53a3c97edf Add (deprecated) swap-serializable-whitelist! for backwards compatibility 2020-11-06 15:34:18 +01:00
Peter Taoussanis
93755570a5 [#137] Add thaw-from-resource 2020-11-06 15:34:18 +01:00
Peter Taoussanis
a98b0d8bb1 java.time.Instant support housekeeping 2020-10-24 16:53:02 +02:00
Peter Taoussanis
2203a4800c [#135 #128] Add support for java.time.Instant (@cnuernber) 2020-10-24 14:38:02 +02:00
Peter Taoussanis
5502e0d479 Misc housekeeping 2020-10-24 14:10:32 +02:00
Peter Taoussanis
9600e8c4cd [#131] Serializable: incl. back-compatibility with *serializable-whitelist* 2020-09-15 09:36:09 +02:00
Peter Taoussanis
4b03616395 [#131] Serializable: make check failure error message clearer 2020-09-15 09:19:10 +02:00
Peter Taoussanis
23400e7735 Serializable: simplify amortized cost impl. 2020-09-12 16:59:56 +02:00
Peter Taoussanis
77203271a0 This should be public :-) 2020-09-12 12:26:18 +02:00
Peter Taoussanis
478160ed85 Serializable: add allow-and-record-any-serializable-class-unsafe
A convenience for folks upgrading from older versions of Nippy
still vulnerable to #130.
2020-09-12 12:16:55 +02:00
Peter Taoussanis
d7229f8665 Serializable: docstring improvements 2020-09-12 11:55:29 +02:00
Peter Taoussanis
ac0df2b307 Return private write-str-<size> fns 2020-09-12 11:55:29 +02:00
Peter Taoussanis
9cac0afb98 Misc housekeeping 2020-09-11 10:43:28 +02:00
Peter Taoussanis
c4251fb39f [BREAKING][#130] Serializable: split *serializable-whitelist* into separate freeze/thaw lists
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.
2020-09-11 10:38:58 +02:00
Peter Taoussanis
057e2f1cd1 Serializable: add read-quarantined-serializable-object-unsafe! util 2020-09-10 22:56:45 +02:00
Peter Taoussanis
db2c22eed8 Serializable: NB freeze default is now always to ALLOW ALL
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.
2020-09-10 22:56:45 +02:00
Peter Taoussanis
db71943a5b [#122] Option to disable freezing and/or thawing of metadata 2020-09-10 22:56:45 +02:00
Peter Taoussanis
8f71638a19 Officially allow binding config via calls to freeze, thaw, etc. 2020-09-10 22:56:45 +02:00
Peter Taoussanis
25706d09d5 [BREAKING] Standardize :nippy/_ response forms 2020-09-10 22:53:45 +02:00
Peter Taoussanis
b4b5450d97 Serializable: mod whitelist check impl. to match Tufte 2020-09-10 22:53:45 +02:00
Peter Taoussanis
252d898ff1 Misc housekeeping 2020-09-10 22:53:45 +02:00
Peter Taoussanis
ee12b40dde Add auto-size read-str 2020-09-10 22:53:45 +02:00
Peter Taoussanis
421d45b3c3 Bump Encore dep (v3.0.0) 2020-09-10 22:53:43 +02:00
Peter Taoussanis
e5a614bd9b *serializable-whitelist*: incl. some basic classes in default 2020-09-10 11:18:43 +02:00
Peter Taoussanis
ee9917d42a Update project.clj, bump deps 2020-09-10 11:05:02 +02:00
Peter Taoussanis
79612437ca [#131] *serializable-whitelist*: add JVM property, env var overrides 2020-08-27 10:34:47 +02:00
Peter Taoussanis
5de70b9516 *serializable-whitelist*: support "*" wildcards in class names 2020-08-27 10:34:28 +02:00
Peter Taoussanis
f9d0123d89 *serializable-whitelist*: improve docstring 2020-08-27 10:31:12 +02:00
Peter Taoussanis
040da54936 [#126] extend-freeze: include id collision odds in docstring 2020-08-27 10:31:01 +02:00
Peter Taoussanis
cf84a441f4 Revert v2.14.2 hotfix reset 2020-07-24 19:38:16 +02:00
Peter Taoussanis
ea93fee8e2 v2.14.2 hotfix 2020-07-24 19:37:11 +02:00
Peter Taoussanis
61fb009fdd [BREAKING] [Security] Fix RCE vulnerability
Fix a Remote Code Execution (RCE) vulnerability identified in an
excellent report by Timo Mihaljov (@solita-timo-mihaljov).

You are vulnerable iff both:

  1. You are using Nippy to serialize and deserialize data from an
     UNTRUSTED SOURCE.

  2. You have a vulnerable ("gadget") class on your classpath.
     Notably Clojure <= 1.8 includes such a class [1].
     Many other libraries do too, some examples at [2].

To prevent this risk, a Serialization whitelist has been added.
Any classes not *explicitly* authorized by the whitelist to use
Serialization will NOT be permitted to.

The default whitelist is EMPTY, meaning this is a BREAKING
change iff you make use of Nippy's Serialization support. In
this case, you'll need to update the whitelist for your needs.

For more info see the `*serializable-whitelist*` docstring.

[1] https://clojure.atlassian.net/browse/CLJ-2204
[2] https://github.com/frohoff/ysoserial

Further info below provided by Timo:
------------------------------------

Deserialization vulnerabilities are exploited by constructing objects of classes
whose constructors perform some action that's useful to the attacker. A class like
this is called a gadget, and a collection of such classes that can be combined to
reach the attacker's goal is called a gadget chain.

There are three prerequisites for exploiting a deserialization vulnerability:

  1) The attacker must be able to control the deserialized data, for example,
     by gaining write access to the data store where trusted parties serialize
     data or by exploiting some other vulnerability on the other end of a
     communications channel.

  2) The deserializer must construct objects of classes specified in the
     serialized data. In other words, the attacker must have full control over
     which classes get instantiated.

  3) The classpath must contain gadgets that can be combined into a gadget chain.

The vulnerable code is in Nippy's function `read-serializable`, which calls the
`readObject` method of `ObjectInputStream`.

I have only tested the PoC with the latest stable version, 2.14.0, but looking at
Nippy's Git history, I believe all versions starting with the following commit
are vulnerable:

    commit 9448d2b3ce
    [Thu Oct 24 13:47:25 2013 +0700]

For a user to be affected, they must:

  1) use Nippy to serialize untrusted input, and
  2) have a gadget chain on their classpath.

I suspect (but haven't verified) that using Nippy's encryption feature prevents
exploitation in some cases, but if it's used to encrypt the communications between
two systems, one compromised endpoint could send encrypted but
attacker-controlled data to the other.

Ysoserial [4] contains a list of some Java libraries with known gadget chains.
If any of those libraries can be found on the user's classpath, they are known
to be vulnerable. (Ysoserial's list is not exhaustive, so even if a user doesn't
have these particular libraries on their classpath, they may still have some
other gadget chains loaded.)

Unfortunately Clojure versions before 1.9 contained a gadget chain in the
standard library [5][6], so all Nippy users running Clojure 1.8 or earlier
are vulnerable. (Note that users of later Clojure versions may or may not
be vulnerable, depending on whether they have gadget chains from other
libraries on their classpath.)

[4] https://github.com/frohoff/ysoserial
[5] https://groups.google.com/forum/#!msg/clojure/WaL3hHzsevI/7zHU-L7LBQAJ
[6] https://clojure.atlassian.net/browse/CLJ-2204
2020-07-24 18:17:25 +02:00
Peter Taoussanis
b6c1c09419 Allow freeze, thaw opts to override bindings 2020-07-24 17:15:40 +02:00
Peter Taoussanis
57eae96c7b Add auto-size read-bytes 2020-07-24 17:10:17 +02:00