Skip to content

fix(xai): guard local media inputs against credential reads - #57727

Closed
kshitijk4poor wants to merge 2 commits into
NousResearch:mainfrom
kshitijk4poor:salvage/57695-xai-media-read-guard
Closed

fix(xai): guard local media inputs against credential reads#57727
kshitijk4poor wants to merge 2 commits into
NousResearch:mainfrom
kshitijk4poor:salvage/57695-xai-media-read-guard

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

xAI image/video generation reads local image_url / reference_image_urls inputs and base64-encodes them into the outbound xAI request without Hermes' read deny-list guard — so a symlink like ~/.hermes/leak.png -> ~/.hermes/auth.json could have its credential-store target embedded in the payload. This applies the same agent.file_safety.get_read_block_error() guard the OpenAI Codex image path already uses, at every local-file byte-read chokepoint in both xAI plugins.

Changes

  • plugins/image_gen/xai/__init__.py: guard _xai_image_field (the image byte-read); read-deny blocks surface as error_type=access_denied in the edit path instead of a mislabeled io_error.
  • plugins/video_gen/xai/__init__.py: guard _image_ref_to_xai_url and _video_ref_to_xai_url (video image + video byte-reads).
  • Both plugins share the same _raise_if_blocked_local_input helper form; the guard fails open only if agent.file_safety is unavailable (defense-in-depth, consistent with the Codex sibling).
  • Regression tests: symlinked auth.json with .png / .mp4 names are blocked across all three read paths.

Validation

Input Before After
Local .png/.mp4 symlink → auth.json credential bytes base64'd into xAI payload ValueError: Access denied — never read
Legitimate local .png encoded to data URI encoded to data URI (unchanged)
Public HTTPS URL / data URI pass-through pass-through (unchanged)
  • Premise confirmed live on main; guard verified to .resolve() symlinks and match the credential denylist.
  • Aligns xAI with the existing Codex image-input guard (plugins/image_gen/openai-codex/__init__.py).
  • Plugin-only diff (no core touches). Guards sit at the true byte-read chokepoints; all local-read sites covered.
  • 44 targeted tests pass; mutation-checked (neutering the guards fails all 3 symlink tests); E2E-verified with real symlinks (all 3 attack vectors blocked, legit input still encodes).

Salvaged from #57695 by @necoweb3; authorship preserved via cherry-pick. Closes #57695.

necoweb3 and others added 2 commits July 3, 2026 18:31
Self-review follow-up on the salvaged NousResearch#57695 credential-read guard:

- image_gen/xai: extract _raise_if_blocked_local_input mirroring the
  video_gen/xai plugin, so both xAI plugins guard local media inputs
  identically instead of one inlining and one using a helper.
- Simplify the guard body in both plugins: only a real deny-list block
  raises ValueError; import/unexpected failures fail open with a debug
  log (defense-in-depth, consistent with the openai-codex sibling). Drops
  the 'except ValueError: raise' clause that coupled recovery to the
  assumption that the only ValueError in the try-block was ours.
- image edit path: surface a read-deny block as error_type=access_denied
  instead of mislabeling it as a generic io_error.
@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) July 3, 2026 13:06
@kshitijk4poor
kshitijk4poor disabled auto-merge July 3, 2026 13:09
kshitijk4poor added a commit to kshitijk4poor/hermes-agent that referenced this pull request Jul 3, 2026
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

Copy link
Copy Markdown
Collaborator Author

Consolidating into #57726. Both PRs salvage @necoweb3's credential-read guard work; they overlapped on the xAI image path (both would have collided on plugins/image_gen/xai/__init__.py at auto-merge). #57726 now covers the whole image + video bug class — openai, openrouter, and xai (image + video) — through a single shared agent.file_safety.raise_if_read_blocked() chokepoint, which is the better structure than the plugin-local guards here. The xAI video coverage and symlink regression tests unique to this PR were folded into #57726.

Closing this in favor of #57726

@alt-glitch alt-glitch added type/security Security vulnerability or hardening comp/plugins Plugin system and bundled plugins 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 added a commit that referenced this pull request Jul 3, 2026
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 #57695 (xAI
image+video) into this PR; #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).
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
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).
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
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).
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
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 deleted the salvage/57695-xai-media-read-guard branch August 5, 2026 07:10
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P1 High — major feature broken, no workaround 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