Serializable: add read-quarantined-serializable-object-unsafe! util
This commit is contained in:
parent
db2c22eed8
commit
057e2f1cd1
2 changed files with 41 additions and 10 deletions
|
|
@ -321,7 +321,9 @@
|
||||||
If `thaw` encounters an unwhitelisted Serialized class:
|
If `thaw` encounters an unwhitelisted Serialized class:
|
||||||
- `thaw` will throw if it's not possible to safely quarantine.
|
- `thaw` will throw if it's not possible to safely quarantine.
|
||||||
- Otherwise the object will be thawed as:
|
- Otherwise the object will be thawed as:
|
||||||
`{:nippy/unthawable {:class-name _ :content <quarantined-ba> ...}}`.
|
`{:nippy/unthawable {:class-name <> :content <quarantined-ba> ...}}`.
|
||||||
|
- Objects thus quarantined may be manually unquarantined with
|
||||||
|
`read-quarantined-serializable-object-unsafe!`.
|
||||||
|
|
||||||
This is a security measure to prevent Remote Code Execution (RCE).
|
This is a security measure to prevent Remote Code Execution (RCE).
|
||||||
|
|
||||||
|
|
@ -1381,6 +1383,27 @@
|
||||||
:content nil
|
:content nil
|
||||||
:exception e}})))
|
:exception e}})))
|
||||||
|
|
||||||
|
(defn read-quarantined-serializable-object-unsafe!
|
||||||
|
"Given a quarantined Serializable object like
|
||||||
|
{:nippy/unthawable {:class-name <> :content <quarantined-ba>}}, reads and
|
||||||
|
returns the object WITHOUT regard for `*serializable-whitelist*`.
|
||||||
|
|
||||||
|
**MAY BE UNSAFE!** Don't call this unless you absolutely trust the payload
|
||||||
|
to not contain any malicious code.
|
||||||
|
|
||||||
|
See `*serializable-whitelist*` for more info."
|
||||||
|
[m]
|
||||||
|
(when-let [m (get m :nippy/unthawable)]
|
||||||
|
(let [{:keys [class-name content]} m]
|
||||||
|
(when (and class-name content)
|
||||||
|
(read-object
|
||||||
|
(DataInputStream. (ByteArrayInputStream. content))
|
||||||
|
class-name)))))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(read-quarantined-serializable-object-unsafe!
|
||||||
|
(thaw (freeze (java.util.concurrent.Semaphore. 1)))))
|
||||||
|
|
||||||
(defn- read-serializable-q
|
(defn- read-serializable-q
|
||||||
"Quarantined => object serialized to ba, then ba written to output stream.
|
"Quarantined => object serialized to ba, then ba written to output stream.
|
||||||
Has length prefix => can skip `readObject` in event of whitelist failure."
|
Has length prefix => can skip `readObject` in event of whitelist failure."
|
||||||
|
|
|
||||||
|
|
@ -276,16 +276,24 @@
|
||||||
|
|
||||||
"Can freeze and thaw Serializable object if approved by whitelist")
|
"Can freeze and thaw Serializable object if approved by whitelist")
|
||||||
|
|
||||||
(is
|
(let [sem (java.util.concurrent.Semaphore. 1)
|
||||||
(= :quarantined
|
ba (nippy/freeze sem #_{:serializable-whitelist "*"})
|
||||||
(get-in
|
thawed (nippy/thaw ba {:serializable-whitelist #{}})]
|
||||||
(nippy/thaw
|
|
||||||
(nippy/freeze (java.util.concurrent.Semaphore. 1)
|
|
||||||
#_{:serializable-whitelist "*"})
|
|
||||||
{:serializable-whitelist #{}})
|
|
||||||
[:nippy/unthawable :cause]))
|
|
||||||
|
|
||||||
"Thaw will quarantine Serializable objects approved when freezing.")
|
(is
|
||||||
|
(= :quarantined (get-in thawed [:nippy/unthawable :cause]))
|
||||||
|
"Serializable objects will be quarantined when approved for freezing but not thawing.")
|
||||||
|
|
||||||
|
(is
|
||||||
|
(instance? java.util.concurrent.Semaphore
|
||||||
|
(nippy/read-quarantined-serializable-object-unsafe! thawed))
|
||||||
|
"Quarantined Serializable objects may still be manually force-read.")
|
||||||
|
|
||||||
|
(is
|
||||||
|
(instance? java.util.concurrent.Semaphore
|
||||||
|
(nippy/read-quarantined-serializable-object-unsafe!
|
||||||
|
(nippy/thaw (nippy/freeze thawed))))
|
||||||
|
"Quarantined Serializable objects are themselves safely transportable."))
|
||||||
|
|
||||||
(is
|
(is
|
||||||
(instance? java.util.concurrent.Semaphore
|
(instance? java.util.concurrent.Semaphore
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue