Skip to content

Unauthenticated SSRF via multimodal image_url/audio/video in swift deploy (no URL filtering) #9740

Description

@geo-chen

Checklist / 检查清单

  • I have searched existing issues, and this is a new bug report. / 我已经搜索过现有的 issues,确认这是一个新的 bug report。

Bug Description / Bug 描述

reported on 12 June 2026 https://github.com/modelscope/ms-swift/security/advisories/GHSA-7mpg-jvqj-ccxr

Summary

The ms-swift deployment server (swift deploy, OpenAI-compatible) fetches multimodal media URLs (image_url, audio_url, video_url) server-side with no validation of the target, and follows redirects. The server binds 0.0.0.0 and runs without authentication by default. An unauthenticated client of a multimodal deployment can therefore make the server issue requests to internal-only services and cloud instance-metadata endpoints. Confirmed against the load_file / load_image: the functions fetched an internal URL with no filter and followed a redirect.

Details

swift/template/vision_utils.py load_file (~line 141) fetches any http(s) path with no checks:

if path.startswith('http'):
    response = session.get(path, **request_kwargs)   # no scheme/IP filter; follows redirects

There is no loopback/private/link-local/metadata filtering anywhere in the function (no ipaddress, is_global, 127.0.0.1, localhost, 169.254, or allow_redirects handling). Reached via /v1/chat/completions: a message image_url.url is extracted in swift/template/template_inputs.py remove_messages_media (~line 127) into the images list, then swift/template/base.py load_image (~line 274) calls load_file. Defaults (swift/arguments/deploy_args.py): host='0.0.0.0' (~line 36), api_key=None (~line 38); swift/pipelines/infer/deploy.py _check_api_key (~line 116) passes when api_key is None. So the endpoint is unauthenticated and network-exposed by default.

How to Reproduce / 如何复现

PoC

scripts/poc_msswift_ssrf.md.

POST /v1/chat/completions
{"model":"<vl-model>","messages":[{"role":"user","content":[
  {"type":"image_url","image_url":{"url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/"}}]}]}

Validated against the load_file / load_image: load_file("http://127.0.0.1:8456/secret.png") hit the local internal listener and returned the bytes (PNG magic confirmed); load_image decoded it; load_file("http://127.0.0.1:8456/redir") followed a 302 to /secret.png (so an attacker host can 302 to http://169.254.169.254/...). Source confirms no URL filter, default host 0.0.0.0, and api_key=None (no auth).

Impact

An unauthenticated client of a multimodal ms-swift deployment can coerce server-side requests to internal services and cloud instance-metadata endpoints (credential theft), and use redirects to reach metadata even if a host allowlist is later added. This is unauthenticated SSRF on the default configuration.

Additional Information / 补充信息

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions