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
docs: expand Taipy showcase with detailed vulnerability analysis
Provide a comprehensive breakdown of the class pollution vulnerability in Taipy to better illustrate its impact and root cause. This update replaces high-level descriptions with specific exploitation scenarios, including remote code execution, denial of service, and sensitive data leakage. These details offer a clearer understanding of the risks associated with unvalidated attribute modification in dynamic state updates.
We identified a class pollution vulnerability in Taipy that allows attackers to overwrite the Taipy runtime context, leading to severe consequences including RCE, Reflected XSS, Denial of Service (DoS), and leakage of sensitive authorization credentials (e.g., OpenAI tokens).
22
+
19
23
## Vulnerability
20
24
21
-
The vulnerability lies in `_attrsetter` in `taipy/gui/utils/_attributes.py`, which processes client update requests via WebSocket:
25
+
The root cause lies in Taipy's use of a recursive set function to update variable values in Taipy states. Both the `name` and `value` parameters are derived from client-side input and lack proper validation. This allows an attacker to inject malicious input, such as `_TpN_tpec_TpExPr_value_TPMDL_2.__class__.__base__.set`, to overwrite the `set` method of `_TaipyBase`.
26
+
27
+
The following functions are invoked in multiple routes via `_manage_message` to update states from the client side:
1. Set up the tutorial case from the [Taipy Getting Started Guide](https://docs.taipy.io/en/latest/tutorials/getting_started/) at `http://localhost:5000`.
69
+
2. Visit the page, intercept the WebSocket request, and replace the `name` field with `_TpN_tpec_TpExPr_value_TPMDL_2.__class__.__base__.set`. This overwrites the `set` method of `_TaipyBase` with a non-callable integer.
3. Refresh the page and observe that dragging the slider causes the application to crash.
76
+
77
+
**Effect**: `_TaipyBase.set` is overwritten with a non-callable integer. Any subsequent state update operation raises `TypeError`, making the application completely unusable for all users.
78
+
79
+
---
80
+
81
+
### Consequence 2: OpenAI Token Leakage
82
+
83
+
**Steps:**
62
84
63
-
Via the same BeautifulSoup entity map technique as django-unicorn:
85
+
1. Set up the LLM ChatBot example from the [Taipy ChatBot Tutorial](https://docs.taipy.io/en/latest/tutorials/articles/chatbot/) at `http://localhost:5000`. The source code can be found [here](https://github.com/Avaiga/demo-chatbot).
86
+
2. Visit the page, send a message (e.g., "hello"), and intercept the WebSocket request. Replace the `name` field with `client.base_url` and the `value` field with an attacker-controlled domain. This step may require multiple attempts to succeed.
3. Send additional messages and observe that requests intended for OpenAI are redirected to the attacker's server, along with the associated OpenAI token.
93
+
94
+
**Effect**: The attacker-controlled `base_url` causes all subsequent API calls (including the `Authorization: Bearer <token>` header) to be sent to the attacker's server, leaking the OpenAI API key.
95
+
96
+
---
97
+
98
+
### Consequence 3: XSS
99
+
100
+
<imgsrc="https://github.com/user-attachments/assets/0aae38bb-8f08-4850-93c0-ffd60d9006ee"alt="Taipy XSS via class pollution"width="100%">
101
+
102
+
In [`taipy/gui/gui.py`](https://github.com/Avaiga/taipy/blob/439c7f52253fc09dd41c455a8a9f8da962d49dfa/taipy/gui/gui.py#L542-L546), when the application attempts to render user content, if the content provider is not found, it falls back to returning `type(content).__name__` as the HTML response:
103
+
104
+
```python
105
+
def_get_user_content_url(self, ...):
106
+
...
107
+
if provider isNone:
108
+
returntype(content).__name__
67
109
```
68
110
69
-
### RCE
111
+
However, the `__name__` attribute of a class object is settable through class pollution, e.g., `tp_TpExPr_gui_get_adapted_lov_past_conversations_NoneType_TPMDL_2_0.__class__.__name__`. An attacker can overwrite this attribute with a malicious HTML or JavaScript payload.
**Effect**: The attacker's script is injected into pages served to users who trigger the content rendering path.
123
+
124
+
---
125
+
126
+
### Consequence 4: RCE
127
+
128
+
<imgsrc="https://github.com/user-attachments/assets/6419bc85-2492-44f2-857e-a7f60158ae31"alt="Taipy RCE via class pollution"width="100%">
129
+
130
+
The class pollution vulnerability allows attackers to set arbitrary attributes on objects that appear in the session state. We found that the `Gui.on_action` route can be leveraged to invoke the `Gui.table_on_edit` method, which allows new objects from the `__main__` module to be bound into the session state. In [`taipy/gui/gui.py`](https://github.com/Avaiga/taipy/blob/439c7f52253fc09dd41c455a8a9f8da962d49dfa/taipy/gui/gui.py#L1872), a `getattr` call on the state object automatically triggers the binding operation, while a subsequent `setattr` immediately resets the bound value to `None`:
131
+
132
+
```python
133
+
setattr(state, var_name, None) # briefly binds the object before resetting
75
134
```
76
135
77
-
### Token Leakage
136
+
This behavior creates a brief race window where object references, such as the `Gui` class, temporarily exist in the session state. During this window, attackers can exploit class pollution to overwrite attributes on those objects.
137
+
138
+
We further discovered that the `Gui.__SELF_VAR` attribute is used as a prefix when constructing expressions passed to Python's built-in `eval()` function in [`taipy/gui/utils/_evaluator.py`](https://github.com/Avaiga/taipy/blob/439c7f52253fc09dd41c455a8a9f8da962d49dfa/taipy/gui/utils/_evaluator.py#L265):
78
139
79
-
Via disabling SSL verification or redirecting API calls:
By overwriting the `__SELF_VAR` value through class pollution, an attacker can control the expression that gets evaluated, ultimately leading to arbitrary code execution on the server.
**Effect**: Arbitrary shell command execution as the Taipy server process user.
172
+
85
173
## Impact
86
174
87
-
Taipy is used in production ML pipelines and data applications. The WebSocket endpoint is accessible to any authenticated user, making this a remote-triggerable vulnerability with severe consequences. Taipy Enterprise promptly patched the issue after responsible disclosure.
175
+
Any user of Taipy can exploit this vulnerability to launch RCE, Reflected XSS, Denial of Service (DoS), and leakage of sensitive authorization credentials (e.g., OpenAI tokens). The WebSocket endpoint is accessible to any user, making this a remote-triggerable vulnerability. Taipy Enterprise promptly patched the issue after responsible disclosure.
88
176
89
177
## Proof of Concept
90
178
91
-
See [`cp-collection/taipy/poc/`](https://github.com/jackfromeast/python-class-pollution/tree/main/cp-collection/taipy/poc) for the full exploit.
1. CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes. <https://cwe.mitre.org/data/definitions/915.html>
189
+
2. Class Pollution leading to RCE in pydash. <https://gist.github.com/CalumHutton/45d33e9ea55bf4953b3b31c84703dfca>
190
+
3. Prototype Pollution in Python. <https://blog.abdulrah33m.com/prototype-pollution-in-python/>
191
+
4. Google Mesop fix (similar vulnerability). <https://github.com/google/mesop/pull/1171>
192
+
5. Liu et al. *The First Large-Scale Systematic Study of Python Class Pollution Vulnerability*. IEEE S&P 2025. <https://jackfromeast.github.io/assets/Pyrl.pdf>
0 commit comments