Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260129162602.46ymqnlk2ixipsjn@jwilk.net>
Date: Thu, 29 Jan 2026 17:26:02 +0100
From: Jakub Wilk <jwilk@...lk.net>
To: oss-security@...ts.openwall.com
Subject: Re: CVE-2025-56005 Undocumented RCE in PLY via
 `picklefile` Parameter

It looks like the pickling feature was removed in 
https://github.com/dabeaz/ply/commit/1fac9fed647909b9 (Feb 2020, 
"Massive refactoring/cleanup"), but that didn't make it into a release. 
But anyway...

* Alan Coopersmith <alan.coopersmith@...cle.com>, 2026-01-28 14:10:
>https://www.cve.org/CVERecord?id=CVE-2025-56005 has added to the 
>references a link to https://github.com/tom025/ply_exploit_rejection 
>which argues that this CVE should be rejected because:
[...]
>>Run
>>
>>    uv run main.py
>>
>>This will run the proof of concept. This results in the program 
>>exiting early with a `AttributeError: 'function' object has no 
>>attribute 'input'`.

I don't know what uv is, but the PoC almost works for me:

    $ python3 -m pip install ply
    Collecting ply
      Downloading ply-3.11-py2.py3-none-any.whl.metadata (844 bytes)
    Downloading ply-3.11-py2.py3-none-any.whl (49 kB)
    Installing collected packages: ply
    Successfully installed ply-3.11

    $ cat /tmp/pwned
    cat: /tmp/pwned: No such file or directory

    $ python3 main.py
    WARNING: yacc table file version is out of date
    WARNING: no p_error() function is defined
    Traceback (most recent call last):
      File "/home/jwilk/ply_exploit_rejection/main.py", line 35, in <module>
        parser.parse('example')
      File ".../lib/python3.12/site-packages/ply/yacc.py", line 333, in parse
        return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File ".../lib/python3.12/site-packages/ply/yacc.py", line 1018, in parseopt_notrack
        lexer = lex.lexer
                ^^^^^^^^^
    AttributeError: module 'ply.lex' has no attribute 'lexer'. Did you mean: 'Lexer'?

The AttributeError is PLY's weird way of saying that you forgot to 
create the lexer. Indeed, the PoC imports the lex() function from 
ply.lex, and then never uses it. But despite that, the planted code was 
executed:

    $ cat /tmp/pwned
    VULNERABLE

>>## Argument 2: The proof of concept does not demonstrate Arbitrary 
>>Code Execution as claimed ##
>>
>>Referring to the proof of concept code this does not demonstrate 
>>Arbitrary Code Execution as there is a single program running and no 
>>untrusted data has been passed between processes. This is not a 
>>demonstration of CWE-502 as claimed.

Meh. The author of the PoC took a shortcut by putting the code that 
generates the malicious pickle and the code that runs the parser in the 
same process, but it doesn't have to be that way. It'd be trivial to 
move the two parts into separate programs.

I've attached a revised PoC:

    $ printf example | python3 parser.py
    example
    $ python3 naughty-pickle.py cowsay pwned > parser.pkl
    $ printf example | python3 parser.py
     _______
    < pwned >
     -------
            \   ^__^
             \  (oo)\_______
                (__)\       )\/\
                    ||----w |
                    ||     ||
    WARNING: yacc table file version is out of date
    example

So there is no doubt that if you let PLY read pickles from untrusted 
source, code execution is possible. But is it really a bug in PLY, or a 
bug in the code that uses PLY in such a foolish way?

-- 
Jakub Wilk

View attachment "parser.py" of type "text/x-python" (341 bytes)

View attachment "naughty-pickle.py" of type "text/x-python" (188 bytes)

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.