fix(caddy): block the unauthenticated beacon validator namespace from public (VANA-BC-001) - #27
Merged
Merged
Conversation
… public
The public Caddy vhost forwarded all of /eth/* to the beacon REST gateway,
which includes Prysm's unauthenticated validator namespace. An unauthenticated
remote POST to /eth/v1/validator/prepare_beacon_proposer overwrites a
proposer's execution-layer fee recipient, and on a node that is both publicly
exposed and actively proposing this redirects the block's priority fees to an
attacker address. /eth/v1/validator/duties/proposer and the
/eth/v{2,3}/validator/blocks endpoints widen the surface. Ref VANA-BC-001.
Deny /eth/v1|v2|v3/validator (and everything under it) on the public path with
a 403, ahead of the public consensus handler. Move the trusted-IP handler ahead
of the public handlers so RPC_TRUSTED_IP_RANGES actually takes effect (it was
dead code, matched after the public wildcards) and the validator client keeps
full access over trusted ranges. Public reads are unchanged.
Left as documented follow-ups: narrow the public consensus handler to an
explicit read-only allowlist, and set CORS_ALLOWED_ORIGINS explicitly instead
of defaulting to *.
Claude-Session: https://claude.ai/code/session_01W58RjBw7v1TvptXHQoDjsA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The public Caddy vhost forwards all of
/eth/*to the beacon REST gateway. That prefix includes Prysm's validator namespace, which is unauthenticated by design (it is meant to be reached only by the validator client on a trusted network). As shipped it is reachable by anyone on the internet.An unauthenticated remote
POST /eth/v1/validator/prepare_beacon_proposerwrites into Prysm'sTrackedValidatorsCache, which is the source ofSuggestedFeeRecipientin the execution payload. The validator client signs the produced block without comparing the payload's fee recipient against its configured one. So on a node that is both publicly exposed and actively proposing, an attacker can set the fee recipient for a validator index and redirect that block's execution-layer priority fees to an address they control. The proposer schedule needed for timing is published by the same namespace (/eth/v1/validator/duties/proposer/{epoch}), and block production (/eth/v{2,3}/validator/blocks/{slot}) is exposed too.Reference: VANA-BC-001. Verified live against
rpc.vana.org(the write returns 200 and reaches the real Prysm handler; a dummy recipient was used, nothing moved) and reproduced locally against this exact config.Fix
/eth/v1|v2|v3/validatorand everything under it on the public path with a 403, ahead of the public consensus handler.@public_el/@public_clmatched first, which also meantRPC_TRUSTED_IP_RANGEShad no effect. Trusted ranges now keep full access to the execution and consensus layers, including the validator namespace the validator client needs.Testing
Reproduced the deployment locally (this Caddyfile in front of a stub beacon) and confirmed:
/eth/v{1,2,3}/validator/*path, includingprepare_beacon_proposer, returns 403/eth/v1/node/syncing,/eth/v1/beacon/genesisand other reads still reach the beacon (200)/still routes to gethcaddy validatepasses.Follow-ups (not in this PR)
CORS_ALLOWED_ORIGINSexplicitly and pass it to the caddy service indocker-compose.ymlinstead of defaulting to*.archive.vana.org:3500reportedly exposes the REST API directly on a public port; apply the same policy there.