People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!
pickle.loads() is the sink to look for. Hugging Face had a vulnerability recently that could have been exploited this way.os.system can be hooked. This part is super easy once we know what's a well-defined "bad sink". PEP 567 has context variables for thread-local state. This can be placed as taint to specify whether the execution is within Pickle or not. This doesn't work in our case because the taint variable could be modified by the runtime itself. So, it was added at the CPython level, making it impossible to alter. Another alternative was to inspect the call stack. However, this has really bad performance penalties and has zero introspective of C code.strncmp() with various packages being checked. For instance, os., ctypes. and many others. This blacklist approach works well but broke a bunch of things. The initial version of this blacklist had easy evasion vectors via using global hooks. Many things still had issues, like multiprocessing. Finally, some calls were unaudited for some attributes and not others, making it incomplete. So, back to the drawing board!import mechanism. By distinguishing between import related events and other operations, it would create a nice boundary. On the actual execution of bytecode, they were then able to use a whitelist of very specific audit events that have no impact. So, this solves the security problem! This has the limitation that it relies on an audit.