Thumbor convolution filter allows divide-by-zero in C extension leading to remote DoS (CVE-2026-53503)
### Summary Thumbor's `filters:convolution(<matrix>, <columns>, <should_normalize>)` filter passes the user-controlled `<columns>` value to a C extension (`thumbor/ext/filters/_convolution.c`) where it is used as a divisor (for `%` and `/`) without validating `columns > 0`. When `columns=0`, the C code triggers undefined behavior; on x86_64 this reliably results in a fatal divide-by-zero trap (SIGFPE) and crashes the Thumbor process (confirmed on Linux x86_64 and macOS Intel x86_64), causing a remote denial of service. ### Details #### Root cause The Python filter accepts `columns=0`, and the native C extension uses `columns_count` as a divisor without validating it. 1) Python filter entry point allows `columns=0` (`thumbor/filters/convolution.py`): ```python @filter_method( r"(?:[-]?[\d]+\.?[\d]*[;])*(?:[-]?[\d]+\.?[\d]*)", BaseFilter.PositiveNumber, # accepts 0 BaseFilter.Boolean, ) async def convolution(self, matrix, columns, should_normalize=True): ... imgdata = _convolution.apply(..., matrix, columns, should_normalize) ``` `BaseFilter.PositiveNumber` matches `"0"` (`thumbor/filters/__init__.py`): ```python class BaseFilter: PositiveNumber = {"regex": r"[\d]+", "parse": int} # matches "0" PositiveNonZeroNumber = {"regex": r"[\d]*[1-9][\d]*", "parse": int} ``` 2) C extension divides/modulos by `columns_count` without a zero check (`thumbor/ext/filters/_convolution.c`): ```c kernel_size = PyTuple_Size(kernel_tuple); if ((kernel_size % columns_count != 0) || (kernel_size % 2 == 0) || ((kernel_size / columns_count) % 2) == 0) { // TODO: error, not a valid kernel return NULL; } ``` ### PoC #### Test environment - Linux x86_64 #### Preconditions - The `convolution` filter is enabled (it is enabled by default via `BUILTIN_FILTERS`). - Either: - `/unsafe/` URLs are allowed (`ALLOW_UNSAFE_URL=True`), OR - `/unsafe/` is disabled, and the attacker has a valid signed URL (i.e., the attacker is an authorized user/partner, or can obtain signed URLs from a trusted signing service). #### Example request (signed URL) `http://<host>:<port>/<url-sign>/400x400/filters:convolution(1;2;1;2;4;2;1;2;1,0,true)/example.jpg` #### Example request (/unsafe/) `http://<host>:<port>/unsafe/400x400/filters:convolution(1;2;1;2;4;2;1;2;1,0,true)/example.jpg` ### Impact - Remote Denial of Service via process crash (SIGFPE) on x86_64 (confirmed on Linux x86_64 and macOS Intel x86_64). - Exploitability depends on deployment: - If `/unsafe/` is enabled: unauthenticated remote DoS. - If `/unsafe/` is disabled: the attacker needs a valid signed URL.(i.e., the attacker is an authorized user/partner, or can obtain signed URLs from a trusted signing service) ### Suggested remediation - In the C extension (`thumbor/ext/filters/_convolution.c`): - Reject `columns_count <= 0` before any `%` or `/`. - In the Python filter (`thumbor/filters/convolution.py`): - Require `columns` to be non-zero (e.g., use `BaseFilter.PositiveNonZeroNumber`).
AI Analysis
Technical Summary
Thumbor's convolution filter accepts a user-controlled 'columns' parameter that is passed to a native C extension without validation for zero. The C extension performs division and modulo operations using this parameter as a divisor, leading to a divide-by-zero trap (SIGFPE) when 'columns' is zero. This causes the Thumbor process to crash, resulting in a remote denial of service. The vulnerability affects Thumbor versions before 7.8.0. Exploitation depends on deployment configuration: unauthenticated if unsafe URLs are allowed, or authenticated if only signed URLs are permitted. The recommended remediation is to validate and reject zero values for 'columns' in both the Python filter and the C extension.
Potential Impact
Successful exploitation causes a remote denial of service by crashing the Thumbor process with a fatal divide-by-zero error. There is no impact on confidentiality or integrity. The exploitability depends on whether unsafe URLs are enabled or if the attacker has access to valid signed URLs.
Mitigation Recommendations
A patch is available for Thumbor to reject zero values for the 'columns' parameter in the convolution filter. Users should upgrade to version 7.8.0 or later where this validation is implemented. The fix includes checks in both the Python filter and the C extension to prevent divide-by-zero errors. Until patched, restricting access to signed URLs and disabling unsafe URLs can reduce exposure.
Thumbor convolution filter allows divide-by-zero in C extension leading to remote DoS (CVE-2026-53503)
Description
### Summary Thumbor's `filters:convolution(<matrix>, <columns>, <should_normalize>)` filter passes the user-controlled `<columns>` value to a C extension (`thumbor/ext/filters/_convolution.c`) where it is used as a divisor (for `%` and `/`) without validating `columns > 0`. When `columns=0`, the C code triggers undefined behavior; on x86_64 this reliably results in a fatal divide-by-zero trap (SIGFPE) and crashes the Thumbor process (confirmed on Linux x86_64 and macOS Intel x86_64), causing a remote denial of service. ### Details #### Root cause The Python filter accepts `columns=0`, and the native C extension uses `columns_count` as a divisor without validating it. 1) Python filter entry point allows `columns=0` (`thumbor/filters/convolution.py`): ```python @filter_method( r"(?:[-]?[\d]+\.?[\d]*[;])*(?:[-]?[\d]+\.?[\d]*)", BaseFilter.PositiveNumber, # accepts 0 BaseFilter.Boolean, ) async def convolution(self, matrix, columns, should_normalize=True): ... imgdata = _convolution.apply(..., matrix, columns, should_normalize) ``` `BaseFilter.PositiveNumber` matches `"0"` (`thumbor/filters/__init__.py`): ```python class BaseFilter: PositiveNumber = {"regex": r"[\d]+", "parse": int} # matches "0" PositiveNonZeroNumber = {"regex": r"[\d]*[1-9][\d]*", "parse": int} ``` 2) C extension divides/modulos by `columns_count` without a zero check (`thumbor/ext/filters/_convolution.c`): ```c kernel_size = PyTuple_Size(kernel_tuple); if ((kernel_size % columns_count != 0) || (kernel_size % 2 == 0) || ((kernel_size / columns_count) % 2) == 0) { // TODO: error, not a valid kernel return NULL; } ``` ### PoC #### Test environment - Linux x86_64 #### Preconditions - The `convolution` filter is enabled (it is enabled by default via `BUILTIN_FILTERS`). - Either: - `/unsafe/` URLs are allowed (`ALLOW_UNSAFE_URL=True`), OR - `/unsafe/` is disabled, and the attacker has a valid signed URL (i.e., the attacker is an authorized user/partner, or can obtain signed URLs from a trusted signing service). #### Example request (signed URL) `http://<host>:<port>/<url-sign>/400x400/filters:convolution(1;2;1;2;4;2;1;2;1,0,true)/example.jpg` #### Example request (/unsafe/) `http://<host>:<port>/unsafe/400x400/filters:convolution(1;2;1;2;4;2;1;2;1,0,true)/example.jpg` ### Impact - Remote Denial of Service via process crash (SIGFPE) on x86_64 (confirmed on Linux x86_64 and macOS Intel x86_64). - Exploitability depends on deployment: - If `/unsafe/` is enabled: unauthenticated remote DoS. - If `/unsafe/` is disabled: the attacker needs a valid signed URL.(i.e., the attacker is an authorized user/partner, or can obtain signed URLs from a trusted signing service) ### Suggested remediation - In the C extension (`thumbor/ext/filters/_convolution.c`): - Reject `columns_count <= 0` before any `%` or `/`. - In the Python filter (`thumbor/filters/convolution.py`): - Require `columns` to be non-zero (e.g., use `BaseFilter.PositiveNonZeroNumber`).
CVSS v3.1
Score 7.5high
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
Thumbor's convolution filter accepts a user-controlled 'columns' parameter that is passed to a native C extension without validation for zero. The C extension performs division and modulo operations using this parameter as a divisor, leading to a divide-by-zero trap (SIGFPE) when 'columns' is zero. This causes the Thumbor process to crash, resulting in a remote denial of service. The vulnerability affects Thumbor versions before 7.8.0. Exploitation depends on deployment configuration: unauthenticated if unsafe URLs are allowed, or authenticated if only signed URLs are permitted. The recommended remediation is to validate and reject zero values for 'columns' in both the Python filter and the C extension.
Potential Impact
Successful exploitation causes a remote denial of service by crashing the Thumbor process with a fatal divide-by-zero error. There is no impact on confidentiality or integrity. The exploitability depends on whether unsafe URLs are enabled or if the attacker has access to valid signed URLs.
Mitigation Recommendations
A patch is available for Thumbor to reject zero values for the 'columns' parameter in the convolution filter. Users should upgrade to version 7.8.0 or later where this validation is implemented. The fix includes checks in both the Python filter and the C extension to prevent divide-by-zero errors. Until patched, restricting access to signed URLs and disabling unsafe URLs can reduce exposure.
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-cqjp-jf4r-h5q9
- Osv Schema Version
- 1.4.0
- Aliases
- ["CVE-2026-53503"]
- Ecosystems
- ["PyPI"]
- Database Specific Severity
- HIGH
- Cvss Version
- 3.1
Threat ID: 6a6cf7ddbf32cb7a342b1c50
Added to database: 07/31/2026, 19:30:37 UTC
Last enriched: 07/31/2026, 20:33:25 UTC
Last updated: 08/01/2026, 02:04:56 UTC
Views: 4
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.