Skip to content

rpc: do not return panic stack traces to callers - #67

Open
DHEBP wants to merge 2 commits into
DEROFDN:community-devfrom
DHEBP:fix/rpc-stack-trace-disclosure
Open

rpc: do not return panic stack traces to callers#67
DHEBP wants to merge 2 commits into
DEROFDN:community-devfrom
DHEBP:fix/rpc-stack-trace-disclosure

Conversation

@DHEBP

@DHEBP DHEBP commented Aug 12, 2026

Copy link
Copy Markdown

What

On panic recovery, the derod RPC handlers and the two tx-verification recover sites formatted debug.Stack() into the returned error. That error becomes the JSON-RPC error body, so any unauthenticated caller can retrieve the node's absolute build path and OS username.

The same disclosure is reachable through DERO.NameToAddress with no crafted transaction: a name whose stored value is not a 33-byte key hits a nil-pointer dereference (the address constructor's error was discarded and a stale error checked in its place), which the recover then turns into a stack-trace response.

DERO.GetGasEstimate leaks the same way at two layers: a panic in the handler frame (e.g. empty params) hits the handler recover, and a panic inside the DVM during simulation is returned as an error from RunSmartContract / Execute_sc_function — both carried debug.Stack().

Change

  • 14 cmd/derod/rpc handlers + 2 blockchain/transaction_verify.go recover sites: log the stack at V(1), return a generic error.
  • NameToAddress: guard on the nil address so malformed stored values return cleanly instead of panicking. Values of 33 bytes (including existing zero-owned names) still resolve exactly as before.
  • dvm: the RunSmartContract and Execute_sc_function recover sites return the panic value only, without the stack. These fire on the block-connect path too, but the error text is never hashed or consumed (block-connect discards it), so this is consensus-inert; the stack is still logged at V(2) on that path.
  • Adds a regression test.

Notes

  • No consensus surface; the changed error strings are not consumed by any caller (checked wallet / p2p / miner).
  • Stack traces remain in the node's own logs for operators.

DHEBP added 2 commits August 12, 2026 01:27
On panic recovery the daemon RPC handlers and the two tx-verification
recover sites formatted debug.Stack() into the returned error, which
becomes the JSON-RPC error body. Any unauthenticated caller could
retrieve the node's absolute build path and OS username. Log the stack
at V(1) and return a generic error instead.

Also fix a nil-pointer dereference in NameToAddress: the address
constructor's error was discarded and a stale error checked in its
place, so a name whose stored value is not a 33-byte key produced a nil
address that was then dereferenced. Guard on the nil address. Values of
33 bytes still resolve as before.
The recover sites in RunSmartContract and Execute_sc_function formatted
debug.Stack() into the returned error. DERO.GetGasEstimate returns that
error to an unauthenticated caller, leaking the node build path. Return
the panic value only; the block-connect path still logs the stack.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant