Skip to content

fix(vision): reject non-image files and blocked URLs - #1940

Closed
Gutslabs wants to merge 1 commit into
NousResearch:mainfrom
Gutslabs:fix/vision-local-file-guard
Closed

fix(vision): reject non-image files and blocked URLs#1940
Gutslabs wants to merge 1 commit into
NousResearch:mainfrom
Gutslabs:fix/vision-local-file-guard

Conversation

@Gutslabs

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes two safety issues in vision_analyze_tool().

Previously:

  • local file paths were accepted without checking whether the file was actually an image
  • blocked URLs could reach the vision download path without website policy enforcement

That meant non-image local files could be base64-encoded and sent to the vision model, and blocked remote URLs could bypass the website policy layer.

This change validates that local files are real images, enforces website policy checks before and after download redirects, and adds regression tests.

Type of Change

  • Bug fix
  • Security fix
  • Tests

Changes Made

  • Reject local files that are not real images
  • Enforce website policy before remote image download
  • Re-check the final redirected URL against website policy
  • Added regression tests for non-image local files and blocked URLs

How to Test

  1. Run source .venv/bin/activate
  2. Run pytest tests/tools/test_vision_tools.py -q
  3. Verify a local text file is rejected before any LLM call
  4. Verify blocked image URLs are denied before download
  5. Verify redirects to blocked final URLs are also denied

teknium1 added a commit that referenced this pull request Mar 30, 2026
#1940)

Three safety gaps in vision_analyze_tool:

1. Local files accepted without checking if they're actually images —
   a renamed text file would get base64-encoded and sent to the model.
   Now validates magic bytes (PNG, JPEG, GIF, BMP, WebP, SVG).

2. No website policy enforcement on image URLs — blocked domains could
   be fetched via the vision tool. Now checks before download.

3. No redirect check — if an allowed URL redirected to a blocked domain,
   the download would proceed. Now re-checks the final URL.

Fixed one test that needed _validate_image_url mocked to bypass DNS
resolution on the fake blocked.test domain (is_safe_url does DNS
checks that were added after the original PR).

Co-authored-by: GutSlabs <GutSlabs@users.noreply.github.com>
teknium1 added a commit that referenced this pull request Mar 30, 2026
#1940) (#3845)

Three safety gaps in vision_analyze_tool:

1. Local files accepted without checking if they're actually images —
   a renamed text file would get base64-encoded and sent to the model.
   Now validates magic bytes (PNG, JPEG, GIF, BMP, WebP, SVG).

2. No website policy enforcement on image URLs — blocked domains could
   be fetched via the vision tool. Now checks before download.

3. No redirect check — if an allowed URL redirected to a blocked domain,
   the download would proceed. Now re-checks the final URL.

Fixed one test that needed _validate_image_url mocked to bypass DNS
resolution on the fake blocked.test domain (is_safe_url does DNS
checks that were added after the original PR).

Co-authored-by: GutSlabs <GutSlabs@users.noreply.github.com>
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #3845. Cherry-picked cleanly onto current main with one test fix (mocked _validate_image_url to bypass newer DNS resolution checks on fake test domains). All three security fixes verified end-to-end: non-image rejection, website policy enforcement, and redirect re-check. Thanks for the solid contribution!

@teknium1 teknium1 closed this Mar 30, 2026
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
NousResearch#1940) (NousResearch#3845)

Three safety gaps in vision_analyze_tool:

1. Local files accepted without checking if they're actually images —
   a renamed text file would get base64-encoded and sent to the model.
   Now validates magic bytes (PNG, JPEG, GIF, BMP, WebP, SVG).

2. No website policy enforcement on image URLs — blocked domains could
   be fetched via the vision tool. Now checks before download.

3. No redirect check — if an allowed URL redirected to a blocked domain,
   the download would proceed. Now re-checks the final URL.

Fixed one test that needed _validate_image_url mocked to bypass DNS
resolution on the fake blocked.test domain (is_safe_url does DNS
checks that were added after the original PR).

Co-authored-by: GutSlabs <GutSlabs@users.noreply.github.com>
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
NousResearch#1940) (NousResearch#3845)

Three safety gaps in vision_analyze_tool:

1. Local files accepted without checking if they're actually images —
   a renamed text file would get base64-encoded and sent to the model.
   Now validates magic bytes (PNG, JPEG, GIF, BMP, WebP, SVG).

2. No website policy enforcement on image URLs — blocked domains could
   be fetched via the vision tool. Now checks before download.

3. No redirect check — if an allowed URL redirected to a blocked domain,
   the download would proceed. Now re-checks the final URL.

Fixed one test that needed _validate_image_url mocked to bypass DNS
resolution on the fake blocked.test domain (is_safe_url does DNS
checks that were added after the original PR).

Co-authored-by: GutSlabs <GutSlabs@users.noreply.github.com>
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
NousResearch#1940) (NousResearch#3845)

Three safety gaps in vision_analyze_tool:

1. Local files accepted without checking if they're actually images —
   a renamed text file would get base64-encoded and sent to the model.
   Now validates magic bytes (PNG, JPEG, GIF, BMP, WebP, SVG).

2. No website policy enforcement on image URLs — blocked domains could
   be fetched via the vision tool. Now checks before download.

3. No redirect check — if an allowed URL redirected to a blocked domain,
   the download would proceed. Now re-checks the final URL.

Fixed one test that needed _validate_image_url mocked to bypass DNS
resolution on the fake blocked.test domain (is_safe_url does DNS
checks that were added after the original PR).

Co-authored-by: GutSlabs <GutSlabs@users.noreply.github.com>
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
NousResearch#1940) (NousResearch#3845)

Three safety gaps in vision_analyze_tool:

1. Local files accepted without checking if they're actually images —
   a renamed text file would get base64-encoded and sent to the model.
   Now validates magic bytes (PNG, JPEG, GIF, BMP, WebP, SVG).

2. No website policy enforcement on image URLs — blocked domains could
   be fetched via the vision tool. Now checks before download.

3. No redirect check — if an allowed URL redirected to a blocked domain,
   the download would proceed. Now re-checks the final URL.

Fixed one test that needed _validate_image_url mocked to bypass DNS
resolution on the fake blocked.test domain (is_safe_url does DNS
checks that were added after the original PR).

Co-authored-by: GutSlabs <GutSlabs@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants