Drop-in replacement for requests with Presidio security hardening. Independent of Microsoft Presidio (a data-anonymization toolkit).
Project description
presidio-hardened-requests
A 100% drop-in replacement for the Python
requests library with automatic
Presidio security hardening (v0.2.0).
# Before (plain requests — no security hardening)
import requests
# After (Presidio hardening — zero code changes needed)
import presidio_requests as requests
Every call you already make — requests.get(), requests.post(),
Session(), etc. — keeps working exactly the same, with security
hardening applied transparently underneath.
Security Features (v0.2.0)
| Feature | What it does |
|---|---|
| Strict TLS 1.2+ enforcement | Rejects TLS 1.0/1.1; enforces strong cipher suites; verify=True always (1.3 max supported) |
| HTTP → HTTPS auto-upgrade | Insecure http:// URLs are silently upgraded to https:// |
| Certificate pinning | Optional per-host SHA-256 cert fingerprint verification (best-effort; documented limitations) |
| Secret redaction | API keys, tokens, passwords, and auth headers (+ params/data/json in logs) scrubbed. Sink-level RedactingFilter enforces for all log records on the presidio_requests logger (new in v0.2) |
| Per-host rate limiting | Intelligent rate limiting with exponential backoff on errors |
| CVE quick-check + pip-audit | On-import static awareness + pip-audit in dev/CI for current coverage |
| Security event logging | Structured logs for every hardening action (presidio_requests logger) |
Installation
pip install presidio-hardened-requests
For development (includes pip-audit):
git clone https://github.com/presidio-v/presidio-hardened-requests.git
cd presidio-hardened-requests
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
v0.2.0 Highlights
- Sink-enforced secret redaction via
RedactingFilter(installed automatically on the logger). - Improved redaction coverage in request logging (params, data, json bodies).
pip-auditadded to dev extras and CI pipeline.- Dependency floors raised; docs aligned with actual implementation (TLS 1.2+, pinning limitations noted).
- All core Presidio security extensions from PRESIDIO-REQ.md now delivered or clearly documented.
Usage
Basic — Zero Code Changes
import presidio_requests as requests
# All your existing code works unchanged
resp = requests.get("https://httpbin.org/get")
print(resp.json())
Secret Redaction in Action
import logging
import presidio_requests as requests
logging.basicConfig(level=logging.DEBUG)
# The Bearer token is automatically redacted in all logs
resp = requests.get(
"https://httpbin.org/get",
headers={"Authorization": "Bearer sk-proj-SUPER_SECRET_KEY"},
)
# Log output shows: Authorization: Bearer ***REDACTED***
Compared to Plain requests
# --- Plain requests (INSECURE) ---
import requests
# ✗ No TLS enforcement — silently allows http://
requests.get("http://api.example.com/data")
# ✗ Secrets visible in logs
requests.get("https://api.example.com?api_key=sk_live_abc123")
# ✗ No rate limiting — can overwhelm servers
for i in range(10000):
requests.get("https://api.example.com/data")
# --- presidio-hardened-requests (SECURE) ---
import presidio_requests as requests
# ✓ Auto-upgrades to https://
requests.get("http://api.example.com/data")
# ✓ api_key redacted in all logs
requests.get("https://api.example.com?api_key=sk_live_abc123")
# ✓ Per-host rate limiting with backoff
for i in range(10000):
requests.get("https://api.example.com/data")
Advanced — HardenedSession
from presidio_requests import HardenedSession, SecretRedactor, RateLimiter
session = HardenedSession(
redactor=SecretRedactor(placeholder="[SCRUBBED]"),
rate_limiter=RateLimiter(max_requests_per_second=5.0),
pinned_certs={"api.example.com": "abcdef1234567890..."},
enforce_tls=True,
)
resp = session.get("https://api.example.com/v1/users")
CVE Quick-Check
from presidio_requests import check_cve
warnings = check_cve()
if warnings:
for w in warnings:
print(f"⚠ {w}")
else:
print("✓ Installed requests version is clean")
Running Tests
pytest -v --cov=presidio_requests --cov-report=term-missing
Project Structure
presidio-hardened-requests/
├── src/presidio_requests/
│ └── __init__.py # Security wrapper (the only source file)
├── tests/
│ ├── test_cve.py # CVE quick-check tests
│ ├── test_drop_in.py # Drop-in API compatibility tests
│ ├── test_rate_limiter.py # Rate limiter tests
│ ├── test_redaction.py # Secret redaction tests
│ ├── test_session.py # HardenedSession tests
│ └── test_tls.py # TLS hardening tests
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── ci.yml # pytest + ruff on every push/PR
│ └── codeql.yml # GitHub CodeQL security scanning
├── pyproject.toml
├── LICENSE # MIT
├── README.md
└── SECURITY.md
License
MIT — see LICENSE.
Security
See SECURITY.md for our vulnerability disclosure policy.
SDLC
This repository is developed under the Presidio hardened-family SDLC: https://github.com/presidio-v/presidio-hardened-docs/blob/main/sdlc/sdlc-report.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file presidio_hardened_requests-0.2.0.tar.gz.
File metadata
- Download URL: presidio_hardened_requests-0.2.0.tar.gz
- Upload date:
- Size: 43.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c9d6555f75d1f6ce3832b926c543c1e1809609f1b5dcc0a5b12b5518521c8cc
|
|
| MD5 |
524fa8b93652b3ead5d552dfffa5a470
|
|
| BLAKE2b-256 |
af2d64160f2426f3f4a575c026111bcc1dbc8353f1389175beff889ee47438e4
|
Provenance
The following attestation bundles were made for presidio_hardened_requests-0.2.0.tar.gz:
Publisher:
publish.yml on presidio-v/presidio-hardened-requests
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
presidio_hardened_requests-0.2.0.tar.gz -
Subject digest:
6c9d6555f75d1f6ce3832b926c543c1e1809609f1b5dcc0a5b12b5518521c8cc - Sigstore transparency entry: 1791641159
- Sigstore integration time:
-
Permalink:
presidio-v/presidio-hardened-requests@e58f7ef83d60b5b418b9b8e9aeac7a6d69d7a27b -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/presidio-v
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e58f7ef83d60b5b418b9b8e9aeac7a6d69d7a27b -
Trigger Event:
push
-
Statement type:
File details
Details for the file presidio_hardened_requests-0.2.0-py3-none-any.whl.
File metadata
- Download URL: presidio_hardened_requests-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad42661bfbe637678b8193ddcf829e9e18877d9c0337e80df9ae4ef0977ff84a
|
|
| MD5 |
b6eda1e7f5c4074b2ffd4913ea078a58
|
|
| BLAKE2b-256 |
7a7bffd12a66f17bc089f2a95ac4690add71f306a5e6c9979d3c2c76be2aa270
|
Provenance
The following attestation bundles were made for presidio_hardened_requests-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on presidio-v/presidio-hardened-requests
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
presidio_hardened_requests-0.2.0-py3-none-any.whl -
Subject digest:
ad42661bfbe637678b8193ddcf829e9e18877d9c0337e80df9ae4ef0977ff84a - Sigstore transparency entry: 1791641194
- Sigstore integration time:
-
Permalink:
presidio-v/presidio-hardened-requests@e58f7ef83d60b5b418b9b8e9aeac7a6d69d7a27b -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/presidio-v
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e58f7ef83d60b5b418b9b8e9aeac7a6d69d7a27b -
Trigger Event:
push
-
Statement type: