Listen to this Post
Thumbor is an open-source photo thumbnail service. Prior to version 7.8.0, the `file_loader` component contains a path traversal vulnerability that allows attackers to read arbitrary files outside the configured FILE_LOADER_ROOT_PATH.
The root cause lies in the order of operations within the `load()` function of thumbor/loaders/file_loader.py. The code performs a security check using `abspath()` and `startswith()` to verify that the requested file path is inside the allowed root directory. However, the URL decoding function `unquote()` is called after this security check. This allows an attacker to use percent-encoded path traversal sequences like `%2e%2e` (which decodes to ..) that are treated as literal directory names during the security check, thereby bypassing it. Only after the check passes does `unquote()` decode them to actual `..` sequences, enabling directory traversal.
The vulnerability is exploitable through the `watermark` and `frame` filters, which pass their URL parameters directly to the loader without re-encoding. This is in contrast to the main image URL flow, which applies `quote()` in `imaging.py` line 37. The default configuration (ALLOW_UNSAFE_URL = True) and the fact that these filters are enabled by default make this vulnerability readily exploitable.
DailyCVE Form
Platform: Thumbor
Version: < 7.8.0
Vulnerability: Path Traversal
Severity: Critical
date: 2026-07-31
Prediction: 2026-08-07
What Undercode Say
Analytics indicate active exploitation attempts in the wild targeting this specific bypass technique. The following bash command demonstrates the proof-of-concept (PoC) for reading /etc/passwd:
curl 'http://thumbor-host:8888/unsafe/filters:watermark(%252e%252e/%252e%252e/%252e%252e/%252e%252e/etc/passwd,0,0,100)/some-valid-image.jpg'
The attack flow is as follows:
1. `%252e%252e` arrives at Tornado and is decoded to %2e%2e.
2. The watermark filter passes `%2e%2e/%2e%2e/…/etc/passwd` to `file_loader`.
3. `join(ROOT, ‘%2e%2e/…’)` results in `ROOT/%2e%2e/…`.
4. `abspath()` sees `%2e%2e` as a literal directory name (no dots to resolve).
5. `startswith(ROOT)` returns `True` (passes the check).
6. `exists()` returns `False` (the literal `%2e%2e` directory doesn’t exist).
7. `unquote()` converts `%2e%2e` to `..`.
- The OS resolves
.., reading files outside theROOT.
Exploit
An attacker can exploit this vulnerability by crafting a URL with double-encoded path traversal sequences and passing it to the `watermark` or `frame` filter. The prerequisites for exploitation are:
– `LOADER = thumbor.loaders.file_loader` (or file_loader_http_fallback)
– `ALLOW_UNSAFE_URL = True` (this is the default)
– watermark/frame filters are enabled by default (in BUILTIN_FILTERS)
Protection
To protect against this vulnerability, update Thumbor to version 7.8.0 or later. This version fixes the path traversal issue by ensuring URL decoding occurs before the security validation. If an immediate update is not possible, consider disabling the `watermark` and `frame` filters or setting `ALLOW_UNSAFE_URL = False` as a temporary workaround.
Impact
Successful exploitation allows for arbitrary file read on the Thumbor server. When the file is a valid image format, its content is returned in the response overlaid as a watermark. This can be used to read sensitive files, such as configuration files, secrets, private keys, and other critical data.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

