CVE-2026-121691 (GCVE-0-2026-121691)

Vulnerability from cvelistv5 – Published: 2026-11-10 17:29 – Updated: 2026-11-10 17:29 X_Open Source
VLAI
Title
Unbounded decompression in the whatstk ZIP loader exhausts memory and disk
Summary
Improper Handling of Highly Compressed Data (CWE-409) in the ZIP loader of whatstk from 0.7.0 before 0.9.0 allows a party that supplies a chat export to exhaust the memory and the disk of the process that parses it, because _str_from_file() (whatstk/whatsapp/parser.py) calls zip_ref.extractall() with no bound on the size of the members and no check of the compression ratio, then reads the extracted file in full with f.read(). The only guard on the archive counts the extracted files and raises when there is not exactly one, but it runs after extractall() has already written them, so it does not prevent the cost. _clean_text() then passes the whole text through unicodedata.normalize("NFKD", text), which holds a second copy, and the parse builds a list of regular expression matches and a DataFrame over it, so peak memory is a multiple of the decompressed text rather than of the archive. A ZIP is a documented input of WhatsAppChat.from_source() and df_from_whatsapp(), and is the form in which WhatsApp exports a chat on iOS, so the attacker supplies the whole file. This results in a small upload costing hundreds of megabytes of memory and of disk, and in the process being killed where that exceeds what is available.
CWE
  • CWE-409 - Improper Handling of Highly Compressed Data (Data Amplification)
Assigner
Secur0 CNA
Impacted products
Vendor Product Version
lucasrodes whatstk Affected: 0.7.0 , < 0.9.0 (semver)
    cpe:2.3:a:lucasrodes:whatstk:*:*:*:*:*:python:*:*
Create a notification for this product.
Show details on NVD website

{
  "containers": {
    "cna": {
      "affected": [
        {
          "collectionURL": "https://pypi.org",
          "defaultStatus": "unaffected",
          "packageName": "whatstk",
          "product": "whatstk",
          "programFiles": [
            "whatstk/whatsapp/parser.py"
          ],
          "repo": "https://github.com/lucasrodes/whatstk",
          "vendor": "lucasrodes",
          "versions": [
            {
              "lessThan": "0.9.0",
              "status": "affected",
              "version": "0.7.0",
              "versionType": "semver"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:lucasrodes:whatstk:*:*:*:*:*:python:*:*",
                  "versionEndExcluding": "0.9.0",
                  "versionStartIncluding": "0.7.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "OR"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Jorge Rey Cotallo (reddev)"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Xo\u00e1n M. Otero Jorge"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Dar\u00edo Rivas"
        },
        {
          "lang": "en",
          "type": "coordinator",
          "value": "Secur0 CNA"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Lucas Rod\u00e9s-Guirao"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "Improper Handling of Highly Compressed Data (CWE-409) in the ZIP loader of whatstk from 0.7.0 before 0.9.0 allows a party that supplies a chat export to exhaust the memory and the disk of the process that parses it, because \u003ccode\u003e_str_from_file()\u003c/code\u003e (\u003ccode\u003ewhatstk/whatsapp/parser.py\u003c/code\u003e) calls \u003ccode\u003ezip_ref.extractall()\u003c/code\u003e with no bound on the size of the members and no check of the compression ratio, then reads the extracted file in full with \u003ccode\u003ef.read()\u003c/code\u003e. The only guard on the archive counts the extracted files and raises when there is not exactly one, but it runs after \u003ccode\u003eextractall()\u003c/code\u003e has already written them, so it does not prevent the cost. \u003ccode\u003e_clean_text()\u003c/code\u003e then passes the whole text through \u003ccode\u003eunicodedata.normalize(\"NFKD\", text)\u003c/code\u003e, which holds a second copy, and the parse builds a list of regular expression matches and a DataFrame over it, so peak memory is a multiple of the decompressed text rather than of the archive. A ZIP is a documented input of \u003ccode\u003eWhatsAppChat.from_source()\u003c/code\u003e and \u003ccode\u003edf_from_whatsapp()\u003c/code\u003e, and is the form in which WhatsApp exports a chat on iOS, so the attacker supplies the whole file. This results in a small upload costing hundreds of megabytes of memory and of disk, and in the process being killed where that exceeds what is available."
            }
          ],
          "value": "Improper Handling of Highly Compressed Data (CWE-409) in the ZIP loader of whatstk from 0.7.0 before 0.9.0 allows a party that supplies a chat export to exhaust the memory and the disk of the process that parses it, because _str_from_file() (whatstk/whatsapp/parser.py) calls zip_ref.extractall() with no bound on the size of the members and no check of the compression ratio, then reads the extracted file in full with f.read(). The only guard on the archive counts the extracted files and raises when there is not exactly one, but it runs after extractall() has already written them, so it does not prevent the cost. _clean_text() then passes the whole text through unicodedata.normalize(\"NFKD\", text), which holds a second copy, and the parse builds a list of regular expression matches and a DataFrame over it, so peak memory is a multiple of the decompressed text rather than of the archive. A ZIP is a documented input of WhatsAppChat.from_source() and df_from_whatsapp(), and is the form in which WhatsApp exports a chat on iOS, so the attacker supplies the whole file. This results in a small upload costing hundreds of megabytes of memory and of disk, and in the process being killed where that exceeds what is available."
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "NONE",
            "attackVector": "LOCAL",
            "baseScore": 6.7,
            "baseSeverity": "MEDIUM",
            "exploitMaturity": "NOT_DEFINED",
            "privilegesRequired": "NONE",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "ACTIVE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "HIGH",
            "vulnConfidentialityImpact": "NONE",
            "vulnIntegrityImpact": "NONE",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-409",
              "description": "CWE-409 Improper Handling of Highly Compressed Data (Data Amplification)",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-11-10T17:29:34.562Z",
        "orgId": "4daa8cea-433a-44bd-9456-53b127fc289a",
        "shortName": "Secur0"
      },
      "references": [
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/lucasrodes/whatstk/pull/182"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/lucasrodes/whatstk/commit/01d66d8"
        },
        {
          "tags": [
            "release-notes"
          ],
          "url": "https://github.com/lucasrodes/whatstk/releases/tag/v0.9.0"
        },
        {
          "tags": [
            "third-party-advisory",
            "technical-description"
          ],
          "url": "https://secur0.com/en/cna/cve-list/cve-2026-121691-whatstk-zip-decompression-bomb"
        }
      ],
      "solutions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "Upgrade to whatstk 0.9.0 or later, which rejects a source larger than 50 MB by default and accepts a \u003ccode\u003emax_size\u003c/code\u003e argument to lower that bound."
            }
          ],
          "value": "Upgrade to whatstk 0.9.0 or later, which rejects a source larger than 50 MB by default and accepts a max_size argument to lower that bound."
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "tags": [
        "x_open-source"
      ],
      "title": "Unbounded decompression in the whatstk ZIP loader exhausts memory and disk",
      "x_generator": {
        "engine": "Vulnogram 1.0.5"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "4daa8cea-433a-44bd-9456-53b127fc289a",
    "assignerShortName": "Secur0",
    "cveId": "CVE-2026-121691",
    "datePublished": "2026-11-10T17:29:34.562Z",
    "dateReserved": "2026-11-03T20:07:54.134Z",
    "dateUpdated": "2026-11-10T17:29:34.562Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.