reward model HTTP service has no authentication, defaults to binding all interfaces, and the training client consumes whatever the endpoint returns
Title
serve_rm.py /get_reward is unauthenticated with --host default 0.0.0.0; the PPO client trusts endpoint-supplied rewards and leaks prompts and completions to the endpoint
Summary
The remote reward model channel has no integrity or authentication on either end:
openrlhf/cli/serve_rm.pyexposesPOST /get_rewardwith no authentication of any kind. The argparse default for--hostis0.0.0.0(binds every interface);--portdefaults to 5000. The shippedexamples/scripts/serve_remote_rm.shonly adds--port.openrlhf/utils/agent.pySingleTurnAgentExecutor._fetch_rewards_via_httpPOSTs{"query": [...], "prompts": [...], "labels": [...]}to each configured URL over plain HTTP and returns the JSON body. The body'srewardsandscoresvalues flow intoExperience.rewardsandExperience.scoreswith no validation, signature, or binding to the request.
Consequences for anyone who can reach the endpoint or intercept the traffic (relevant to the documented multi-node ray deployments, where the reward service regularly runs on a different node):
- Verdict injection: whoever answers on the URL controls the training signal. A malicious or squatted listener returns chosen rewards for every sample and steers the policy update. Because the scheme is plain HTTP with no auth, the same holds for an on-path attacker.
- Data exfiltration: every request body contains the full prompts and the policy completions ("query"). An endpoint owner or MITM harvests the training corpus and model outputs.
- In tool-using agentic rollouts, the policy itself can make outbound HTTP calls if the user-provided agent module gives it such tools; the reward endpoint then also becomes reachable from the evaluated side.
Affected version
Pinned commit 3c3be6234e0cb353e76bb8019947db9dfe99fca7 (tag v0.11.0, 2026-08-13). Files: openrlhf/cli/serve_rm.py (route at lines 128 to 135, host default at line 85), openrlhf/utils/agent.py (_fetch_rewards_via_http at lines 322 to 356, consumption at lines 284 to 297).
Steps to reproduce
Repro directory: poc_f2_reward_channel (poc.py plus REPRO.sh). Loopback only, no model inference:
- The pinned
serve_rm.pyargparse defaults are read programmatically from the file (AST):--hostdefault"0.0.0.0",--portdefault5000, no auth anywhere in the file. - The real
SingleTurnAgentExecutor._fetch_rewards_via_httpis called against a loopback server standing in for an unprivileged peer that bound the reward port first. The server returns a chosen reward (0.9876543) plus an attacker-controlledextra_logsdict. - The server also records the request it received.
Observed output (deterministic across two runs):
"B_verdict_injection": {"attacker_reward_value": 0.9876543, "client_accepted_rewards": 0.9876543, "accepted": true}
"C_data_exfiltrated_to_endpoint_owner": {"keys_seen_by_server": ["labels", "prompts", "query"],
"query_leaks_prompt_and_response": true}Impact
Any actor with network reach to the reward service (or on-path between trainer and service) controls the reward signal of an RLHF run and reads its prompts and completions. Default exposure is widened by --host 0.0.0.0. Severity depends on deployment: loopback single-host deployments are exposed to any local process; multi-node ray deployments are exposed to the cluster network and whatever routes between nodes.
Suggested fix
- Default
--hostto127.0.0.1and require an explicit flag to bind wider. - Add a shared-secret or mutual-TLS option to both
serve_rm.pyand_fetch_rewards_via_http, and validate response shape (finite floats, count matches the request) before consumption. - Document the trust assumption of the reward channel in the multi-node guides.
- Consider hashing request and response into a run log so silent reward divergence is detectable after the fact.
Classification notes
Second executed instance of the "unauthenticated evaluation control plane" genus first minted from AgentBench (R03E1-M2, filed against THUDM/AgentBench for the agentrl worker API). Here the control plane is the reward channel itself rather than a results API. PUBLIC-READY: standard hardening advisory, requires a network or local-process position.
Source: OpenRLHF/OpenRLHF