You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Transition the landing page management to a Hugo-based system to simplify future maintenance and content updates. This change introduces structured source files including markdown content and layouts, while refreshing the landing page with expanded information on research impact, detection methodology, and recent vulnerability findings.
<imgclass="hero-icon" src="img/icon.png" alt="Python Class Pollution">
26
-
<pclass="justified">
27
-
A class pollution vulnerability occurs when attacker-controlled input modifies unintended objects through Python's class-based inheritance model. It arises two core Python language design: (i) <strong>uniform data model</strong>, where every value is an object with attributes like <code>__class__</code> and <code>__globals__</code>, and (ii) its <strong>flexible reflection mechanism</strong>, such as dynamic <code>getattr</code> and <code>setattr</code>.
28
-
</p>
29
-
<pclass="justified">
30
-
The attacker leverages a sequence of reflective attribute lookups with attacker-controlled names to traverse objects and modify attributes in unintended classes or modules. The exploitation of class pollution can lead to various severe consequences including remote code execution (RCE), authentication bypass, cross-site scripting (XSS), denial-of-service (DoS), etc.
31
-
</p>
32
-
33
-
<p>
34
-
This research was presented at <ahref="https://www.ieee-security.org/TC/SP2025/">IEEE S&P 2026</a> by Zhengyu Liu, Jiacheng Zhong, Jianjia Yu, Muxi Lyu, Zifeng Kang, and Yinzhi Cao.
35
-
</p>
36
-
37
-
<h2>History</h2>
38
-
<p>
39
-
Class pollution was <ahref="https://blog.abdulrah33m.com/prototype-pollution-in-python/">first introduced</a> in 2023 by Abdulraheem Khaled <sup><ahref="https://blog.abdulrah33m.com/prototype-pollution-in-python/">[1]</a></sup>, who disclosed a real-world vulnerability in the <ahref="https://github.com/dgilland/pydash">pydash</a> library. It was originally called "Prototype Pollution in Python" due to its similarity to <ahref="https://portswigger.net/web-security/prototype-pollution">JavaScript prototype pollution</a>.
40
-
</p>
41
-
<p>
42
-
Since then, only one additional CVE (<ahref="https://nvd.nist.gov/vuln/detail/CVE-2024-5452">CVE-2024-5452</a>) was discovered before our study. In 2023, Ouyang <sup><ahref="https://ieeexplore.ieee.org/abstract/document/10145365">[2]</a></sup> demonstrated the feasibility of class pollution attacks through a small, synthetic example. In 2024, Zhang <sup><ahref="https://doi.org/10.54254/2755-2721/43/20230839">[3]</a></sup> explored an exploitation technique targeting global variables pollution and discussed two possible defenses.
43
-
</p>
44
-
<p>
45
-
Our work (2026) <sup><ahref="https://jackfromeast.github.io/assets/Pyrl.pdf">[4]</a></sup> introduces a systematic taxonomy of class pollution (five of six variants are novel), an automated detection tool (Pyrl), and a large-scale measurement of class pollution vulnerabilities across the Python ecosystem—uncovering 47 zero-day vulnerabilities in widely used applications and packages.
46
-
</p>
47
-
48
-
<h2>How does it work?</h2>
49
-
<p>
50
-
Consider a common recursive update function intended to set nested fields of an object based on user input:
<imgclass="hero-icon" src="img/icon.png" alt="Python Class Pollution">
25
+
<pclass="justified">
26
+
Python class pollution is a vulnerability class where untrusted input allows attackers to modify unintended Python runtime objects.
27
+
It arises from two core Python language features: (i) a <strong>uniform object model</strong>, where every value is an object and objects expose references to their classes, metadata, and related runtime state through built-in attributes such as <code>__class__</code>, <code>__base__</code>, <code>__dict__</code>, and <code>__globals__</code>;
28
+
and (ii) <strong>flexible reflection mechanisms</strong>, such as dynamic <code>getattr</code> and <code>setattr</code>, which allow programs to access and modify attributes using runtime-determined names.
29
+
</p>
30
+
<pclass="justified">
31
+
The combination of these two language features becomes dangerous when a program performs a sequence of reflective attribute or item lookups using attacker-controlled names. These lookups may cause the program to traverse from an ordinary object to unintended runtime objects through those built-in attributes, and then modify their content that later affect program behavior.
32
+
These modifications violate runtime integrity and can lead to severe consequences, including remote code execution (RCE), authentication bypass, cross-site scripting (XSS), denial of service (DoS), and token leakage.
33
+
</p>
34
+
<h2>How does it work?</h2>
35
+
<p>Consider a common recursive update function intended to set nested fields of an object based on user input:</p>
If <code>data</code> is attacker-controlled, it can be crafted to access unintended objects by traversing Python's built-in attributes. In the example above, the attacker uses the key <code>__class__</code> to retrieve the class object of <code>user</code> via <code>getattr</code>, then sets its <code>__getattribute__</code> method to a non-callable string. Since Python implicitly invokes <code>__getattribute__</code> for all attribute accesses, this triggers a runtime exception on any access to <code>User</code> instances, resulting in a denial-of-service (DoS).
66
-
</p>
67
-
68
-
<p>
69
-
To further exploit class pollution toward severe consequences, e.g., RCE, XSS, auth bypass, we need to consider (i) <ahref="wiki/docs/taxonomy/">pollution primitives</a> (how can attacker-controlled input resolve and modify objects), (ii) <ahref="wiki/docs/targets/">pollution targets</a> (what are the valuable targets to pollute and how will they affect the Python runtime), and (iii) <ahref="wiki/docs/gadgets/">gadgets</a> (how can polluted values lead to concrete impacts). See the <ahref="wiki/docs/">full wiki</a> for details.
70
-
</p>
71
-
72
-
<h2>Attack demonstrations</h2>
73
-
<p>
74
-
Here, we show a zero-day class pollution vulnerablity found in <ahref="https://github.com/django-commons/django-unicorn/security/advisories/GHSA-g9wf-5777-gq43">django-unicorn (CVE-2025-24370)</a> can be exploited to lead to the following four types of consequences:
75
-
</p>
76
-
77
-
<divclass="demos">
78
-
<figure>
79
-
<imgsrc="img/xss.gif" alt="Stored XSS via BeautifulSoup entity map overwrite">
80
-
<figcaption>Stored XSS via BeautifulSoup entity map overwrite</figcaption>
81
-
</figure>
82
-
<figure>
83
-
<imgsrc="img/auth-bypass.gif" alt="Authentication bypass via Django SECRET_KEY pollution">
84
-
<figcaption>Authentication bypass via Django SECRET_KEY pollution</figcaption>
85
-
</figure>
86
-
<figure>
87
-
<imgsrc="img/dos.gif" alt="Denial of Service via decorator corruption">
88
-
<figcaption>Denial of Service via decorator corruption</figcaption>
89
-
</figure>
90
-
<figure>
91
-
<imgsrc="img/rce.gif" alt="Remote Code Execution via os.environ.BROWSER pollution">
92
-
<figcaption>Remote Code Execution via os.environ.BROWSER pollution</figcaption>
93
-
</figure>
94
-
</div>
95
-
96
-
<h2>CVEs at a glance</h2>
97
-
<p>
98
-
We applied our detection tool <strong>Pyrl</strong> to over <strong>671K</strong> Python packages from GitHub and PyPI. It reported <strong>868</strong> alerts, of which <strong>47</strong> were confirmed as exploitable zero-day vulnerabilities:
<p>If <code>data</code> is attacker-controlled, it can be crafted to access unintended objects by traversing Python’s built-in attributes. In the example above, the attacker uses the key <code>__class__</code> to retrieve the class object of <code>user</code> via <code>getattr</code>, then sets its <code>__getattribute__</code> method to a non-callable string. Since Python implicitly invokes <code>__getattribute__</code> for all attribute accesses, this triggers a runtime exception on any access to <code>User</code> instances, resulting in a denial-of-service (DoS).</p>
48
+
<p>To further exploit class pollution toward severe consequences, e.g., RCE, XSS, authentication bypass, we need to consider (i) <ahref="wiki/docs/taxonomy/">pollution primitives</a> (how can attacker-controlled input resolve and modify objects), (ii) <ahref="wiki/docs/targets/">pollution targets</a> (what are the valuable targets to pollute and how will they affect the Python runtime), and (iii) <ahref="wiki/docs/gadgets/">gadgets</a> (how can polluted values lead to concrete impacts). See the <ahref="wiki/docs/">full wiki</a> for details.</p>
49
+
<h2>Why does it matter?</h2>
50
+
<p>Class pollution matters because it violates Python runtime integrity. Once unintended runtime objects are polluted, the modified values may flow into security-sensitive sinks and lead to serious consequences. As an example, we show how a zero-day class pollution vulnerability in <ahref="https://github.com/django-commons/django-unicorn/security/advisories/GHSA-g9wf-5777-gq43">django-unicorn (CVE-2025-24370)</a> can be exploited to cause four types of impact:</p>
51
+
<divclass="demos">
52
+
<figure>
53
+
<imgsrc="img/xss.gif" alt="Stored XSS via BeautifulSoup entity map overwrite">
54
+
<figcaption>Stored XSS via BeautifulSoup entity map overwrite</figcaption>
55
+
</figure>
56
+
<figure>
57
+
<imgsrc="img/auth-bypass.gif" alt="Authentication bypass via Django SECRET_KEY pollution">
58
+
<figcaption>Authentication bypass via Django SECRET_KEY pollution</figcaption>
59
+
</figure>
60
+
<figure>
61
+
<imgsrc="img/dos.gif" alt="Denial of Service via decorator corruption">
62
+
<figcaption>Denial of Service via decorator corruption</figcaption>
63
+
</figure>
64
+
<figure>
65
+
<imgsrc="img/rce.gif" alt="Remote Code Execution via os.environ.BROWSER pollution">
66
+
<figcaption>Remote Code Execution via os.environ.BROWSER pollution</figcaption>
67
+
</figure>
68
+
</div>
69
+
<p>For payloads and technical details, see the <ahref="/wiki/docs/collection/showcases/django-unicorn/">full django-unicorn showcase</a>.</p>
70
+
<h2>How to detect it?</h2>
71
+
<p>To detect class pollution at scale, we built <strong>Pyrl</strong> (/pɜːrl/, “Pearl”), the <em>first</em> automated detection tool for Python class pollution. Pyrl introduces a novel static analysis called <em>operational taint analysis</em>, implemented on top of CodeQL, that precisely models the reflective attribute and item lookups used to traverse and modify objects, and tracks attacker-controlled inputs through them with a set of fine-grained, expressive semantic taint labels.</p>
72
+
<p>Pyrl detects all six variants in our <ahref="wiki/docs/taxonomy/">taxonomy</a>, performs exploitability checking, and uses barrier-node analysis to suppress false positives from key sanitization and type checks. Across over <strong>671K</strong> Python packages, it has identified <strong>47</strong> confirmed zero-day class pollution vulnerabilities.</p>
73
+
<p>To run it on your own code, see the <ahref="wiki/docs/tool/pyrl/">Pyrl documentation</a> for installation and usage.</p>
74
+
<h2>CVEs at a glance</h2>
75
+
<p>A selective list of the confirmed class pollution vulnerabilities:</p>
<p>Class pollution was <ahref="https://blog.abdulrah33m.com/prototype-pollution-in-python/">first introduced</a> in 2023 by Abdulraheem Khaled <sup><ahref="https://blog.abdulrah33m.com/prototype-pollution-in-python/">[1]</a></sup>, who disclosed a real-world vulnerability in the <ahref="https://github.com/dgilland/pydash">pydash</a> library. It was originally called “Prototype Pollution in Python” due to its similarity to <ahref="https://portswigger.net/web-security/prototype-pollution">JavaScript prototype pollution</a>.</p>
124
+
<p>Since then, only one additional CVE (<ahref="https://nvd.nist.gov/vuln/detail/CVE-2024-5452">CVE-2024-5452</a>) was discovered before our study. In 2023, Ouyang <sup><ahref="https://ieeexplore.ieee.org/abstract/document/10145365">[2]</a></sup> demonstrated the feasibility of class pollution attacks through a small, synthetic example. In 2024, Zhang <sup><ahref="https://doi.org/10.54254/2755-2721/43/20230839">[3]</a></sup> explored an exploitation technique targeting global variables pollution and discussed two possible defenses.</p>
125
+
<p>Our work (2026) <sup><ahref="https://jackfromeast.github.io/assets/Pyrl.pdf">[4]</a></sup> introduces a systematic taxonomy of class pollution (five of six variants are novel), an automated detection tool (Pyrl), and a large-scale measurement of class pollution vulnerabilities across the Python ecosystem, uncovering 47 zero-day vulnerabilities in widely used applications and packages.</p>
126
+
<h2>Citation</h2>
127
+
<p><ahref="https://jackfromeast.github.io/assets/Pyrl.pdf">This research</a> was presented at IEEE S&P 2026 by Zhengyu Liu, Jiacheng Zhong, Jianjia Yu, Muxi Lyu, Zifeng Kang, and Yinzhi Cao. Please feel free to cite our paper!</p>
0 commit comments