In MediaManager._process_upload_media_job (langfuse/_task_manager/media_manager.py), the SDK decides whether an upload target is a GCS bucket with a substring check:
is_self_hosted_gcs_bucket = "storage.googleapis.com" in upload_url
If that matches, the SDK skips the x-ms-blob-type and x-amz-checksum-sha256 headers.
Because it is a substring match on the whole URL, it also matches URLs that are not GCS, for example:
https://example.com/upload?next=storage.googleapis.com (string in the query)
https://storage.googleapis.com.example.com/upload (string as a prefix of another domain)
Those uploads are then sent without the headers the SDK would normally add for S3/Azure targets, including the SHA-256 checksum header.
The upload URL comes from the Langfuse server, so I don't see this as exploitable in a normal setup. It is a hardening / correctness fix: the check should look at the URL hostname rather than the raw string.
Proposed fix
Parse the URL and treat it as GCS only when the hostname is storage.googleapis.com or ends with .storage.googleapis.com. Existing behaviour for real GCS URLs (path-style and bucket.storage.googleapis.com) is unchanged.
I have a small PR ready with a unit test in tests/unit/test_media_manager.py that fails before the change and passes after. Happy to open it if this looks good.
Environment
- langfuse-python 4.16.0 (current
main)
In
MediaManager._process_upload_media_job(langfuse/_task_manager/media_manager.py), the SDK decides whether an upload target is a GCS bucket with a substring check:If that matches, the SDK skips the
x-ms-blob-typeandx-amz-checksum-sha256headers.Because it is a substring match on the whole URL, it also matches URLs that are not GCS, for example:
https://example.com/upload?next=storage.googleapis.com(string in the query)https://storage.googleapis.com.example.com/upload(string as a prefix of another domain)Those uploads are then sent without the headers the SDK would normally add for S3/Azure targets, including the SHA-256 checksum header.
The upload URL comes from the Langfuse server, so I don't see this as exploitable in a normal setup. It is a hardening / correctness fix: the check should look at the URL hostname rather than the raw string.
Proposed fix
Parse the URL and treat it as GCS only when the hostname is
storage.googleapis.comor ends with.storage.googleapis.com. Existing behaviour for real GCS URLs (path-style andbucket.storage.googleapis.com) is unchanged.I have a small PR ready with a unit test in
tests/unit/test_media_manager.pythat fails before the change and passes after. Happy to open it if this looks good.Environment
main)