[
https://issues.apache.org/jira/browse/TINKERPOP-3281?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18123548#comment-18123548
]
ASF GitHub Bot commented on TINKERPOP-3281:
-------------------------------------------
Iryna-Kahamlyk opened a new pull request, #3703:
URL: https://github.com/apache/tinkerpop/pull/3703
JIRA: https://issues.apache.org/jira/browse/TINKERPOP-3281
GraphBinary sized heap allocations from an unvalidated 4-byte length prefix
before reading the payload, so a tiny pre-auth frame (~6–21 bytes) could
request gigabytes of memory and OOM Gremlin Server or a connecting driver.
**Changes**
This was already fixed on 3.7-dev in
https://github.com/apache/tinkerpop/pull/3610. However, the same fix does not
work on master. A shared `readSizePrefix()` in `SimpleTypeSerializer` that
unconditionally calls `buffer.readableBytes()` would break the active streaming
driver path. Instead, validation is split based on how the prefix is used, with
`readableBytes()` checked only when the buffer can report it.
The following helpers were added:
* `readByteLength()` — fixed-size byte allocations (String, BigInteger,
Binary/ByteBuffer); rejects negative values, enforces an explicit cap, and
checks `readableBytes()` when known.
* `readElementCount()` — growable containers (List/Set/Map/Tree/Graph);
rejects negative values and checks `readableBytes()` when known, with no
explicit cap.
* `readFixedArrayCount()` — fixed arrays (P arguments); validated like byte
lengths since the array cannot grow incrementally.
* `cappedInitialCapacity()` — caps speculative ArrayList/HashMap pre-sizing.
These are applied across StringSerializer, BigIntegerSerializer,
BinarySerializer, CollectionSerializer(List/Set), MapSerializer,
TreeSerializer, GraphSerializer, ListSerializer, and PSerializer.
> GraphBinary deserializer unbounded pre-allocation from length prefixes
> ----------------------------------------------------------------------
>
> Key: TINKERPOP-3281
> URL: https://issues.apache.org/jira/browse/TINKERPOP-3281
> Project: TinkerPop
> Issue Type: Bug
> Components: io
> Affects Versions: 4.0.0, 3.7.7, 3.8.2
> Reporter: Guian Gumpac
> Priority: Major
> Fix For: 3.7.7, 3.8.2
>
>
> GraphBinary value types size a heap allocation (or bound a read loop) from a
> 4-byte length/count prefix before the payload is read or checked against the
> bytes actually remaining. Because GraphBinary is deserialized
> pre-authentication on the default wire path, a tiny malformed frame (~6-21
> bytes) can declare a multi-hundred-megabyte to multi-gigabyte allocation and
> drive Gremlin Server to OutOfMemoryError. maxContentLength bounds the frame,
> not a single declared length, and the binary decoder catches only
> SerializationException, so the OOM escapes. The surface is symmetric: a
> malicious or on-path server can OOM a connecting driver the same way. The
> same shape recurs across String, Collection (list/set), Map, BigInteger,
> InetAddress, ByteBuffer, Bytecode, P, Tree, graph and BulkSet.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)