Skip to main content

Drop-in replacement for requests with Presidio security hardening. Independent of Microsoft Presidio (a data-anonymization toolkit).

Project description

presidio-hardened-requests

CI CodeQL License: MIT Python 3.9+

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-audit added 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

presidio_hardened_requests-0.2.0.tar.gz (43.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

presidio_hardened_requests-0.2.0-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file presidio_hardened_requests-0.2.0.tar.gz.

File metadata

File hashes

Hashes for presidio_hardened_requests-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6c9d6555f75d1f6ce3832b926c543c1e1809609f1b5dcc0a5b12b5518521c8cc
MD5 524fa8b93652b3ead5d552dfffa5a470
BLAKE2b-256 af2d64160f2426f3f4a575c026111bcc1dbc8353f1389175beff889ee47438e4

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file presidio_hardened_requests-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for presidio_hardened_requests-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ad42661bfbe637678b8193ddcf829e9e18877d9c0337e80df9ae4ef0977ff84a
MD5 b6eda1e7f5c4074b2ffd4913ea078a58
BLAKE2b-256 7a7bffd12a66f17bc089f2a95ac4690add71f306a5e6c9979d3c2c76be2aa270

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page