# Attacker can add arbitrary data to the blockchain without paying gas

Missing end-of-data check in Transaction::rlpParse lets an attacker append arbitrary RLP bytes to a valid transaction, which propagate and get mined without paying gas.

- Payout: hidden
- Severity: critical
- Program: Rootstock Labs
- Found by: ahook
- Disclosed: 2019-09-18
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/396954
- Library page: https://bugbountylibrary.com/r/h1%3A396954
- Tags: area:web3 domain:web3 impact:dos impact:integrity kind:bounty platform:hackerone sev:critical tech:evm technique:source-review vuln:business-logic vuln:deserialization

**Target:** Transaction RLP decoder in rskj Java node
**Root cause:** Transaction::rlpParse decodes the expected fields but never verifies the RLP stream is fully consumed, so trailing bytes are accepted. getEncoded() returns the raw bytes including the extra data while getRawEncoded() used for signature verification ignores it.
**Steps:**
1. Start a regtest mining node: `java -Dblockchain.config.name=regtest -cp rskj-core/build/libs/rskj-core-0.5.0-SNAPSHOT-all.jar co.rsk.Start`
2. Start a second non-mining node configured to peer with the first (`ip.list = ["<target_ip>:50501"]`, `server.enabled = false`)
3. Patch getEncoded to append extra RLP element (e.g. `RLP.encodeElement(Hex.decode("beefbeef..."))`) to the encoded transaction list
4. Send a transaction via `eth_sendTransaction` from the patched node
5. Observe the tx propagate to the clean mining node and be mined; query `eth_getBlockByHash` and see `beefbeef` bytes in the raw block
**How found:** Code review of Transaction::rlpParse noticed no check that the RLP stream was fully consumed after decoding all fields; then verified that getEncoded returns raw bytes while signature verification uses getRawEncoded, allowing the extra data to survive validation.
**Exploitation:** Attacker runs a modified node that appends arbitrary RLP-encoded bytes to a valid signed transaction. The tx propagates over p2p, passes validation on clean nodes (signature check uses getRawEncoded which ignores trailing data), and is mined into a block. Alternatively a malicious miner can append data to any pooled tx, or an attacker can intercept pending txs, append data, and rebroadcast.
**Insight:** When auditing RLP/deserialization parsers, check whether the decoder verifies full stream consumption; also compare which byte representation is used for hashing/signature vs. storage/propagation, since a mismatch lets trailing bytes ride along.

