Skip to content

fix(image-gen/video-gen): guard local provider inputs against credential reads via one shared chokepoint (salvages #57698, consolidates #57695) - #57726

Merged
kshitijk4poor merged 3 commits into
NousResearch:mainfrom
kshitijk4poor:salvage-57698
Jul 3, 2026
Merged

fix(image-gen/video-gen): guard local provider inputs against credential reads via one shared chokepoint (salvages #57698, consolidates #57695)#57726
kshitijk4poor merged 3 commits into
NousResearch:mainfrom
kshitijk4poor:salvage-57698

Conversation

@kshitijk4poor

@kshitijk4poor kshitijk4poor commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Image and video generation providers read model/tool-supplied local image_url / reference_image_urls (and video) paths and base64-inline them into the outbound provider request without Hermes' get_read_block_error() read guard. A path to a Hermes credential store (auth.json, .anthropic_oauth.json, .env, …) — including via a leak.png -> auth.json symlink — could be read and embedded in the payload. The OpenAI Codex image provider already guards this; this PR mirrors that boundary to every image + video provider through one shared chokepoint.

Salvages #57698 (@necoweb3, openai+openrouter image) and consolidates #57695 (@necoweb3, xAI image+video) — cherry-picked to preserve authorship, extended to the whole bug class, verified end-to-end.

Changes

  • agent/file_safety.py: new shared raise_if_read_blocked(path) chokepoint (co-located with get_read_block_error). Best-effort/defense-in-depth: a real block raises ValueError; unexpected internal errors fail open.
  • plugins/image_gen/openai, openrouter, xai: route local-input reads through the shared helper (after the http/https/data: early-returns — remote URLs/data URIs untouched).
  • plugins/video_gen/xai: guard _image_ref_to_xai_url + _video_ref_to_xai_url (video image + video byte-reads) through the same shared helper.
  • Tests upgraded from pass-on-any-ValueError to real security invariants: no-read spies (blocked credential never read into memory), negative controls (legit local image loads; remote/data URIs pass through), and symlink→auth.json regression tests for image + video paths.

Validation

Input Before After
Local .png/.mp4 symlink → auth.json (any provider) credential bytes base64'd into payload ValueError: Access denied — never read
Legitimate local image encoded encoded (unchanged)
Public HTTPS / data URI pass-through pass-through (unchanged)
  • Premise confirmed live on main; get_read_block_error .resolve()s symlinks and matches the profile-aware credential denylist.
  • Single enforced chokepoint — a new provider gets the guard with a one-line call instead of copy-pasted try/except.
  • Plugins-only + the shared agent/file_safety.py helper they all call (the helper is the whole point of the consolidation; it lives in core so every provider shares one auditable boundary).
  • 195 image_gen + video_gen tests pass; mutation-checked (neutering the guards fails every symlink test); E2E-verified with real symlinks across all image + video read paths.

Closes #57698. Closes #57695.

necoweb3 and others added 2 commits July 3, 2026 18:29
… chokepoint + cover xai (NousResearch#57698)

Follow-up to the per-provider guards. Three improvements from review:

1. Extract agent.file_safety.raise_if_read_blocked() as a single shared
   chokepoint and route the OpenAI, OpenRouter, and (newly) xAI image
   providers through it, replacing the 3x-duplicated inline try/except.
   Fixes the whole bug class: xai/_xai_image_field read a model-supplied
   local path via open() with no guard — the same vulnerability the PR
   fixed for OpenAI/OpenRouter, in a sibling provider it missed.
2. Strengthen the regression tests from pass-on-any-ValueError to true
   security invariants: spy open()/read_bytes() and assert the blocked
   credential is NEVER read; add negative controls (legit local image
   still loads; remote/data: URIs pass through unguarded) so a
   block-everything regression can't pass.
3. Guard is best-effort by design (defense-in-depth, not a security
   boundary) — documented on the shared helper.

- agent/file_safety.py: raise_if_read_blocked()
- plugins/image_gen/{openai,openrouter,xai}: route through helper
- tests: no-read spies + negative controls across all three providers
Fold the xAI video credential-read guard into the same shared
agent.file_safety.raise_if_read_blocked chokepoint this PR introduces for
the image providers, so the whole image+video bug class is covered by one
enforced boundary. Consolidates the parallel salvage of NousResearch#57695 (xAI
image+video) into this PR; NousResearch#57727 is now redundant and will be closed.

- video_gen/xai: guard _image_ref_to_xai_url and _video_ref_to_xai_url
  (the video image + video byte-read chokepoints) via the shared helper.
- Regression tests: symlinked auth.json with .png/.mp4 names are blocked
  across both video read paths (mutation-checked).
@kshitijk4poor kshitijk4poor changed the title fix(image-gen): guard local provider inputs against credential reads via one shared chokepoint (salvage #57698) fix(image-gen/video-gen): guard local provider inputs against credential reads via one shared chokepoint (salvages #57698, consolidates #57695) Jul 3, 2026
@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) July 3, 2026 13:12
@kshitijk4poor
kshitijk4poor merged commit 1042329 into NousResearch:main Jul 3, 2026
29 checks passed
@alt-glitch alt-glitch added type/security Security vulnerability or hardening comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/plugins Plugin system and bundled plugins provider/openai OpenAI / Codex Responses API provider/openrouter OpenRouter aggregator provider/xai xAI (Grok) tool/vision Vision analysis and image generation sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data P1 High — major feature broken, no workaround labels Jul 3, 2026
@kshitijk4poor
kshitijk4poor deleted the salvage-57698 branch August 5, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/plugins Plugin system and bundled plugins P1 High — major feature broken, no workaround provider/openai OpenAI / Codex Responses API provider/openrouter OpenRouter aggregator provider/xai xAI (Grok) sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data tool/vision Vision analysis and image generation type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants