presidio-hardened-requests
A 100% drop-in replacement for the Python
requests library with automatic
Presidio security hardening (v0.2.1).
# 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 (any case) are upgraded to https://; any non-HTTPS hop, including a redirect, is refused with InsecureTransportError |
| Certificate pinning | Optional per-host SHA-256 fingerprint, checked during the TLS handshake of every connection to that host (including redirect hops); a mismatch raises CertificatePinError |
| Secret redaction | API keys, tokens, passwords, cookies and auth headers (+ params/data/json in logs, matched by key name and by value) 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.2 Highlights
- Security fix (GHSA-cmr9-799c-jmhv):
- the HTTPS upgrade now handles any scheme case and leading whitespace;
- every request and redirect hop must be HTTPS when
enforce_tls=True; - certificate pins are enforced on the request's own connection and fail closed;
- log redaction also matches credential key names (
X-API-Key,Cookie,api_key, nested JSON) and URL passwords.
pinned_certsvalues must be SHA-256 hex fingerprints (colons allowed); invalid values raiseValueError.
v0.2.1 Highlights
- Security patch: requires
certifi>=2026.10.19, soverify=Trueno longer trusts emSign ECC Root CA - G3 (eMudhra intermediates with trivially recoverable keys, Mozilla bug 2083449).requestsdoes not check revocation, so only the bundle removal protects callers.
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 on the open-source baseline of the PRESIDIO hardened-family SDLC (report · PDF). The controls measured for it, and any open gaps, are its row in the applicability matrix.
Metadata
Release files for presidio-hardened-requests 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| presidio_hardened_requests-0.2.2.tar.gz | 47.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| presidio_hardened_requests-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 59.8 kB
Release files / presidio_hardened_requests-0.2.2.tar.gz
| Download URL | presidio_hardened_requests-0.2.2.tar.gz |
|---|---|
| Size | 47.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
12810484710311fec7c0eae45e07d7abc91ea5e4a46dbbf0c5c908c9b9afdee2
|
|
BLAKE2b-256 checksum How to use checksums |
10bf3c96a8b7e9532503bc3483a0c1173f73bad5ee4e021255fc288902e54d3b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / presidio_hardened_requests-0.2.2-py3-none-any.whl
| Download URL | presidio_hardened_requests-0.2.2-py3-none-any.whl |
|---|---|
| Size | 11.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4fb81a2e21cf24fb077bfbc15a99abaf46e45734d2d3a37fba9749ce36e427fd
|
|
BLAKE2b-256 checksum How to use checksums |
5a21152280df5dbcb2c33b41c641a79c98e1fe91fb2c1bad83f8261379180ece
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logSecurity for presidio-hardened-requests 0.2.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for presidio_hardened_requests-0.2.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.