Visitar URL original
A stranger that writes this node's own id as requestor and a member as addressee makes this node reset its channel to that member every 5 s · Issue #10225 · ArcadeData/arcadedb · GitHub
Skip to content

A stranger that writes this node's own id as requestor and a member as addressee makes this node reset its channel to that member every 5 s #10225

Closed

Description

@robfrank

Follow-up of #10144 (found while fixing it, out of its scope).

Summary

RaftHAServer.onMisdirectedRaftRequest decides that a refused Raft RPC is a self-dial - and resets this node's replication channel to the addressed peer - with member && localPeerId.equals(requestor). requestor is the unauthenticated RaftRpcRequestProto.requestorId header field (GuardedRaftServer.refuseIfMisdirected), never checked against the connection it arrived on.

#10144 stops that field from choosing the throttle slot. It still chooses the action: a sender outside the cluster that addresses a request to a member (replyId = a declared peer id, e.g. arcadedb-1) and writes this node's own id as requestor makes this node close and rebuild its working gRPC channel to that member, once per MISDIRECTED_RECOVERY_INTERVAL_MS (5 s) per member, for as long as it keeps sending. Each reset fails the in-flight appendEntries on that channel and forces a reconnect.

The same shape arises without an attacker: two clusters with the stock arcadedb-0/1/2 naming whose DNS overlaps, which is the shape #10016 was written for.

Where

  • ha-raft/src/main/java/com/arcadedb/server/ha/raft/RaftHAServer.java, onMisdirectedRaftRequest, the worker body: final boolean selfDial = member && localPeerId.equals(requestor);
  • ha-raft/src/main/java/com/arcadedb/server/ha/raft/ratis/GuardedRaftServer.java, refuseIfMisdirected: requestor read verbatim from the header.

Possible fixes

  • Confirm the self-dial from something the sender cannot write: the address this node holds for addressedTo resolves to one of this node's own listener endpoints (host AND Raft port, since several nodes may share a host), which the worker already resolves for its log line; or
  • compare against the transport identity (gRPC TRANSPORT_ATTR_REMOTE_ADDR, or the TLS peer identity when ha.ssl is on) via a server interceptor.

Why not in #10144

#10144 is about the throttle slot. Authenticating the requestor needs either new gRPC plumbing into the guard or an endpoint-equality check against this node's own listeners, a separate change with its own tests.

Activity

  1. added
    haHigh availability / replication (Raft)
    on Oct 17, 2026
  2. added
    grpcgRPC wire protocol (grpc/grpc-client/grpcw)
    severity:minorCosmetic, documentation, edge case, or a workaround exists
    on Oct 17, 2026
  3. added this to the 26.11.1 milestone on Oct 18, 2026
  4. self-assigned this
    on Oct 18, 2026
  5. added a commit that references this issue on Oct 18, 2026
  6. robfrank commented on Oct 18, 2026

    @robfrank
    CollaboratorAuthor

    Fixed in #10300. A refused Raft RPC whose header named this node as the sender used to make the node reset its replication channel to the addressed member. That header field is not authenticated, so any sender could trigger the reset. The node now also checks where the connection actually came from, and resets only when it originates on this host (loopback or a local interface address). A claim from anywhere else is refused and logged. Genuine self-dials also have their own throttle slots, so foreign traffic cannot crowd out a real repair.

    Still open (tracked in #10299):

    • A sender on the same host (another process, a local proxy or sidecar) still passes the source check: an address identifies a host, not a node.
    • A self-dial through an address-translating hop (Docker userland proxy, hairpin NAT, Toxiproxy) is now refused and logged but not repaired. The self-dial cases seen so far (name resolving to loopback or to the node's own IP) are unaffected.

    ❤️ Thanks for helping make ArcadeDB better! ArcadeDB is free and open source, sustained by its community. If it's useful to you or your company, please consider becoming a sponsor to keep development going.

  7. removed
    in progressThe team is actively working on this issue
    on Oct 18, 2026
  8. added a commit that references this issue on Nov 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

buggrpcgRPC wire protocol (grpc/grpc-client/grpcw)haHigh availability / replication (Raft)securityseverity:minorCosmetic, documentation, edge case, or a workaround exists

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions