When using httpx, developers must assume a secure-by-default posture regarding TLS verification and standard authorization header stripping, but remain vigilant around redirect boundaries, ambient proxy lookup, and custom header leakage. The library protects transport channels and manages connection pooling by default, but relies heavily on developer discipline to set explicit timeouts, validate untrusted inputs, and protect sensitive custom headers. Mistakes related to URL parsing, payload sizes, and resource management should fail closed to prevent out-of-memory errors and server-side request forgery.
Essential implementation rules
Validate Untrusted URLs and Handle Parsing Exceptions
Always parse user-supplied URL strings using httpx.URL and wrap request calls or parsing logic in try-except blocks catching httpx.InvalidURL. Enforce strict URL schemes (http and https) to prevent parser differential vulnerabilities and invalid input interpretations.
Maintain Strict TLS and Certificate Verification Settings
Keep certificate verification enabled by retaining verify=True or supplying a configured ssl.SSLContext instance. Never pass verify=False in production code. Use explicit ssl.SSLContext objects for custom certificate authorities, client certificates, and explicit environment variable bindings, and set the sni_hostname request extension when connecting directly to IP addresses.
Configure Explicit Timeouts and Connection Limits
Always configure explicit non-zero timeouts using httpx.Timeout or numeric values to prevent stalled connections from hanging indefinitely. Define explicit connection pool limits using httpx.Limits on transports to prevent unbounded socket allocation and resource exhaustion.
Disable Ambient Proxy Lookup in Untrusted Runtimes
When instantiating httpx.Client or httpx.AsyncClient in multi-tenant or untrusted environments where ambient environment variables may be manipulated by external actors, explicitly pass trust_env=False to prevent external proxy injection.
Enforce Redirect Boundary Validation and Control
Maintain follow_redirects=False by default or strictly validate destination URLs before following HTTP redirects to prevent unintended credential leakage and server-side request forgery.
Stream Large Response Payloads and Enforce Size Limits
Leverage httpx.stream() to inspect response content length or process incoming chunks incrementally, avoiding full memory allocation of large unbounded payloads and preventing denial of service.
Prevent Sensitive Credential Leaks Across Requests and Redirects
Explicitly strip sensitive client default headers or custom authentication keys before dispatching third-party requests or when crossing cross-origin redirect boundaries where custom headers are not automatically purged.
Sanitize and Obfuscate Credentials in Logs and Telemetry
Rely on built-in credential obfuscation like repr() for httpx.URL instances containing embedded basic authentication, and explicitly filter or redact custom sensitive headers and API keys before recording header dictionaries in application logs or event hooks.
Authenticate Requests Securely Using Explicit Parameters
Provide authentication credentials explicitly via the auth parameter, ensuring Basic authentication is used exclusively over HTTPS. Override sync and async auth flows for custom I/O, and explicitly set requires_request_body = True or requires_response_body = True on custom httpx.Auth subclasses when inspecting payloads.
Isolate Client Instances and Configure Persistent Cookies Safely
Supply persistent cookies upon client creation rather than reusing a single client across multiple user sessions to prevent cross-session cookie leakage and unintended token exposure.
Configure Transport Retries for Transient Connection Errors
Explicitly set the retries parameter on httpx.HTTPTransport to handle transient connection errors safely, noting that transport retries apply exclusively to connection errors and timeouts.
Enforce Automated HTTP Status Validation via Event Hooks
Register a response event hook calling response.raise_for_status() to consistently enforce status code checks globally and trigger httpx.HTTPStatusError on HTTP 4xx or 5xx responses.
httpx: All Security Cards
Approximately 4,074 tokens
On this card
Category: api contract misuse
Declare Body Requirements in Custom Authentication Flows
Use when
Developing custom authentication flows by subclassing httpx.Auth that inspect request or response content.
Secure rules
Rule 1: Explicitly set body requirement flags on custom authentication classes before accessing request or response payloads.
When creating a custom authentication subclass of httpx.Auth, you must explicitly set requires_request_body = True or requires_response_body = True on the class if your authentication flow inspects request.content or response.content. Failing to declare these requirements will cause request execution failures or stream-handling bugs.
Authenticate HTTPX Requests Securely Using Explicit Credentials and Custom Flows
Use when
When establishing client authentication, passing credentials, or implementing custom authentication handlers in HTTPX.
Secure rules
Rule 1: Pass explicit authentication parameters using the auth argument
Provide authentication credentials by explicitly passing the auth parameter to the client or request. For HTTP Basic authentication the auth argument may be a two-tuple of username and password.
Rule 2: Use Basic authentication exclusively over HTTPS connections.
HTTP Basic authentication transmits credentials encoded in simple Base64 without transport-layer encryption. Ensure requests target https:// scheme URLs when using httpx.BasicAuth or credential tuples to prevent eavesdropping and interception across the network.
Rule 3: Override sync and async auth flows for custom authentication I/O.
When implementing custom authentication subclasses of httpx.Auth that perform I/O, override .sync_auth_flow() and .async_auth_flow() rather than .auth_flow() to defer execution to appropriate synchronous or asynchronous contexts.
Rule 4: Explicitly disable client authentication per request when accessing public resources.
When a client is initialized with a default auth handler, override it per-request by passing auth=None when making requests to public or third-party endpoints to prevent leaking bearer tokens or credentials to unauthorized hosts.
Disable Environment Variable Proxy Reading in Untrusted Runtimes
Use when
Instantiating an httpx.Client or httpx.AsyncClient in multi-tenant or untrusted environments where ambient environment variables may be manipulated by external actors.
Secure rules
Rule 1: Disable ambient environment proxy lookup by setting trust_env=False on client instantiation.
By default, HTTPX reads ambient proxy settings from the environment. In untrusted or multi-tenant runtimes, explicitly pass trust_env=False to prevent external injection of proxy variables from redirecting client traffic.
Configure Explicit SSL Contexts and Maintain Certificate Verification
Use when
Configuring client certificate validation, custom CA bundles, or connecting over HTTPS using HTTPX.
Secure rules
Rule 1: Maintain certificate verification and never disable TLS checks.
Keep the default verification settings active by retaining verify=True or supplying a configured ssl.SSLContext instance. Never pass verify=False in production environments, as doing so completely disables certificate authority and host identity checks.
Rule 2: Use explicit SSL contexts for custom certificate authorities and client certificates.
Avoid passing file path strings or cert parameters directly to verify= or client initializations, as these legacy patterns trigger deprecation warnings in HTTPX 0.28.x. Instead, instantiate an explicit ssl.SSLContext using ssl.create_default_context() and load custom CA bundles or client certificate chains directly onto the context before passing it to verify.
Rule 3: Set the SNI hostname extension when requesting explicit IP addresses.
When making HTTPS requests directly to an IP address instead of using DNS resolution, explicitly supply the expected domain name using the sni_hostname request extension so HTTPX performs proper server name indication and certificate hostname validation.
Configure Secure TLS and Certificate Verification in HTTPX
Use when
Instantiating HTTPX clients or making HTTPS requests where TLS certificate verification, custom CA bundles, or IP-based SNI mapping must be securely enforced.
Secure rules
Rule 1: Configure SSL and TLS verification settings during client initialization rather than passing per-request SSL arguments.
When using HTTPX Client instances, pass TLS configuration parameters upon client instantiation. If distinct TLS configurations are needed, instantiate separate Client instances for each configuration because per-request SSL arguments are not supported.
Rule 2: Set the sni_hostname request extension when connecting directly to IP addresses for TLS verification.
When making HTTPS requests directly to an explicit IP address rather than a domain name, pass the expected server domain using the sni_hostname request extension so HTTPX can perform correct certificate hostname verification.
Rule 3: Use explicit ssl.SSLContext objects for custom certificates and client credentials.
Avoid passing deprecated string file paths or cert parameters directly. Build an explicit ssl.SSLContext using ssl.create_default_context() and load client certificate chains using ctx.load_cert_chain().
Rule 4: Explicitly inspect SSL environment variables when building custom SSLContext objects.
Because HTTPX does not automatically read SSL_CERT_FILE or SSL_CERT_DIR environment variables when custom contexts are used, explicitly retrieve and pass them to the ssl.SSLContext constructor.
Rule 5: Keep default TLS verification enabled and never disable it in production code.
Rely on HTTPX’s default SSL verification or supply an authenticated ssl.SSLContext object. Never pass verify=False in production code to prevent man-in-the-middle attacks.
Handle InvalidURL exceptions when parsing untrusted URLs
Use when
Constructing HTTP requests from untrusted user input that may contain control characters or malformed syntax.
Secure rules
Rule 1: Catch httpx.InvalidURL exceptions when passing untrusted user input to request methods.
HTTPX’s URL parser explicitly rejects URLs containing ASCII non-printable control characters by raising httpx.InvalidURL. Wrap client request calls in a try-except block catching httpx.InvalidURL to ensure control-character injection attempts do not crash application logic.
Validate and parse untrusted URLs using HTTPX native parsing
Use when
When processing external or untrusted URL strings to prevent parser differentials and invalid input interpretations before executing HTTP requests.
Secure rules
Rule 1: Instantiate httpx.URL and catch httpx.InvalidURL exceptions when handling external or untrusted URL strings.
Always parse user-supplied URL strings with httpx.URL and handle httpx.InvalidURL before executing requests to ensure strict WHATWG URL specification compliance and prevent parser differential vulnerabilities.
import httpxdef safe_fetch(user_supplied_url: str): try: url = httpx.URL(user_supplied_url) except httpx.InvalidURL: raise ValueError("Provided string is not a valid URL") if url.scheme not in ("http", "https"): raise ValueError("Unsupported URL scheme") with httpx.Client() as client: return client.get(url)
Category: interface protocol hardening
Configure explicit transport retries for transient connection errors
Use when
Configuring HTTPX clients to handle connection failures and transient network timeouts safely using transport-level retries.
Secure rules
Rule 1: Configure explicit connection retries on httpx.HTTPTransport using the retries parameter.
Explicitly set the retries parameter on httpx.HTTPTransport to handle transient connection errors safely. Note that HTTPX transport retries only apply to httpx.ConnectError and httpx.ConnectTimeout, and do not automatically retry read/write errors or HTTP 5xx responses.
import httpxtransport = httpx.HTTPTransport(retries=3)with httpx.Client(transport=transport) as client: response = client.get("https://example.com")
Category: network boundary
Control Redirect Boundary Enforcement and Destination Validation
Use when
Making HTTP requests where automatic redirects might cross network boundaries or expose sensitive credentials to untrusted origins.
Secure rules
Rule 1: Keep redirect following disabled or explicitly inspect redirect destinations before proceeding.
Maintain follow_redirects=False by default or strictly validate destination URLs before following HTTP redirects to prevent unintended credential leakage and SSRF.
import httpxresponse = httpx.get("http://example.com/", follow_redirects=False)if response.is_redirect: next_url = response.next_request.url # Perform boundary and scheme checks on next_url before making a request
Category: resource exhaustion
Configure Explicit Timeouts and Connection Pool Limits for HTTP Requests
Use when
When building HTTP client requests and managing connection transports to prevent thread starvation and resource exhaustion.
Secure rules
Rule 1: Always configure explicit non-zero timeouts and avoid using unbounded client settings.
Set explicit network and connection timeouts using httpx.Timeout or pass a direct numeric timeout value to prevent stalled connections from hanging indefinitely and consuming worker threads.
Rule 2: Define explicit connection pool limits on transports to prevent unbounded socket allocation.
Configure connection limits on HTTPTransport and AsyncHTTPTransport using custom Limits objects to protect system file descriptors and prevent socket exhaustion under heavy application traffic.
Stream Large Response Payloads and Enforce Size Limits
Use when
When downloading files or retrieving large response bodies to prevent out-of-memory crashes and denial of service.
Secure rules
Rule 1: Use response streaming to validate content size before reading payloads into memory.
Leverage httpx.stream() to inspect response content length or process incoming chunks incrementally, avoiding full memory allocation of large unbounded payloads.
import httpxMAX_ALLOWED_BYTES = 10 * 1024 * 1024with httpx.stream("GET", "https://example.com/large-file") as response: content_length = int(response.headers.get("Content-Length", 0)) if content_length < MAX_ALLOWED_BYTES: response.read() data = response.text else: raise ValueError("Response payload exceeds maximum allowed size.")
Category: secret handling
Prevent sensitive credential leaks across requests and redirects
Use when
When developers configure client instances with default headers or custom authentication properties, or manage redirection behaviors.
Client-level default headers are automatically included on all outgoing requests sent through that client instance, which can accidentally leak secret tokens or API keys to unintended hosts. Use client.build_request() and explicitly remove sensitive credentials before dispatching requests to public or third-party URLs.
import httpxheaders = {"X-Api-Key": "secret-api-token", "X-Client-ID": "ABC123"}with httpx.Client(headers=headers) as client: request = client.build_request("GET", "https://public-api.example.com") del request.headers["X-Api-Key"] response = client.send(request)
Rule 2: Prevent sensitive header leaks during cross-origin redirects
While HTTPX automatically strips standard Authorization headers on cross-origin redirects, custom API key headers are not automatically purged. When follow_redirects is enabled, ensure custom sensitive headers are not forwarded to untrusted third-party redirect locations, or manage redirects explicitly.
import httpxwith httpx.Client(follow_redirects=False) as client: response = client.get( "https://api.example.com/data", headers={"X-Api-Key": "secret-token-123"} ) if response.is_redirect: target_url = response.headers["location"] if target_url.startswith("https://api.example.com/"): response = client.get(target_url, headers={"X-Api-Key": "secret-token-123"})
Redact and sanitize sensitive credentials in logs and telemetry outputs
Use when
When developers are logging HTTP request objects, response headers, URLs, or implementing request event hooks and diagnostics.
Secure rules
Rule 1: Rely on built-in credential obfuscation for URL representations
When logging httpx.URL instances containing embedded basic authentication credentials, use repr() or string formatting specifiers like %r to automatically mask passwords as [secure] instead of converting the URL to a string.
import httpxurl = httpx.URL("https://user:secret_pass@example.com/api")logger.info("Connecting to %r", url)
Rule 2: Sanitize custom credentials in request headers before logging
Because HTTPX automatically obfuscates standard authorization headers but does not mask custom sensitive headers like API keys or cookies, developers must explicitly filter or redact custom credential keys before recording header dictionaries in application logs or event hooks.
def log_request(request: httpx.Request) -> None: headers = dict(request.headers) if "authorization" in headers: headers["authorization"] = "[REDACTED]" logger.info("Outgoing request to %s with headers %s", request.url, headers)client = httpx.Client(event_hooks={"request": [log_request]})
Category: security control integrity
Enforce Automated HTTP Status Validation Using Response Hooks
Use when
When registering response event hooks on an HTTPX client to consistently enforce status code checking across all operations.
Secure rules
Rule 1: Register a response event hook that calls response.raise_for_status() to automatically enforce status code checks globally.
Use event hooks to guarantee that every client response triggers an httpx.HTTPStatusError on HTTP 4xx or 5xx responses, preventing application logic flaws or security control bypasses from unhandled error responses.
Isolate Client Instances and Configure Cookies at Initialization
Use when
Managing session state and cookie persistence across requests when using httpx.Client.
Secure rules
Rule 1: Configure persistent session cookies during client instantiation to prevent cross-session leakage.
Supply persistent cookies upon client creation rather than passing per-request cookies or reusing a single client across multiple user sessions. Reusing a single client instance causes session cookies set by one server response to persist and automatically attach to subsequent requests, potentially leaking sensitive session tokens across distinct user contexts.
import httpx# Configure cookies at client initialization per sessiondef fetch_user_data(user_cookies: dict) -> httpx.Response: with httpx.Client(cookies=user_cookies) as client: return client.get("https://example.org/echo_cookies")
Declare Body Requirements in Custom Authentication Flows
Approximately 240 tokens
Use when
Developing custom authentication flows by subclassing httpx.Auth that inspect request or response content.
Secure rules
Rule 1: Explicitly set body requirement flags on custom authentication classes before accessing request or response payloads.
When creating a custom authentication subclass of httpx.Auth, you must explicitly set requires_request_body = True or requires_response_body = True on the class if your authentication flow inspects request.content or response.content. Failing to declare these requirements will cause request execution failures or stream-handling bugs.
Authenticate HTTPX Requests Securely Using Explicit Credentials and Custom Flows
Approximately 544 tokens
Use when
When establishing client authentication, passing credentials, or implementing custom authentication handlers in HTTPX.
Secure rules
Rule 1: Pass explicit authentication parameters using the auth argument
Provide authentication credentials by explicitly passing the auth parameter to the client or request. For HTTP Basic authentication the auth argument may be a two-tuple of username and password.
Rule 2: Use Basic authentication exclusively over HTTPS connections.
HTTP Basic authentication transmits credentials encoded in simple Base64 without transport-layer encryption. Ensure requests target https:// scheme URLs when using httpx.BasicAuth or credential tuples to prevent eavesdropping and interception across the network.
Rule 3: Override sync and async auth flows for custom authentication I/O.
When implementing custom authentication subclasses of httpx.Auth that perform I/O, override .sync_auth_flow() and .async_auth_flow() rather than .auth_flow() to defer execution to appropriate synchronous or asynchronous contexts.
Rule 4: Explicitly disable client authentication per request when accessing public resources.
When a client is initialized with a default auth handler, override it per-request by passing auth=None when making requests to public or third-party endpoints to prevent leaking bearer tokens or credentials to unauthorized hosts.
Disable Environment Variable Proxy Reading in Untrusted Runtimes
Approximately 187 tokens
Use when
Instantiating an httpx.Client or httpx.AsyncClient in multi-tenant or untrusted environments where ambient environment variables may be manipulated by external actors.
Secure rules
Rule 1: Disable ambient environment proxy lookup by setting trust_env=False on client instantiation.
By default, HTTPX reads ambient proxy settings from the environment. In untrusted or multi-tenant runtimes, explicitly pass trust_env=False to prevent external injection of proxy variables from redirecting client traffic.
Configure Explicit SSL Contexts and Maintain Certificate Verification
Approximately 1,070 tokens
Use when
Configuring client certificate validation, custom CA bundles, or connecting over HTTPS using HTTPX.
Secure rules
Rule 1: Maintain certificate verification and never disable TLS checks.
Keep the default verification settings active by retaining verify=True or supplying a configured ssl.SSLContext instance. Never pass verify=False in production environments, as doing so completely disables certificate authority and host identity checks.
Rule 2: Use explicit SSL contexts for custom certificate authorities and client certificates.
Avoid passing file path strings or cert parameters directly to verify= or client initializations, as these legacy patterns trigger deprecation warnings in HTTPX 0.28.x. Instead, instantiate an explicit ssl.SSLContext using ssl.create_default_context() and load custom CA bundles or client certificate chains directly onto the context before passing it to verify.
Rule 3: Set the SNI hostname extension when requesting explicit IP addresses.
When making HTTPS requests directly to an IP address instead of using DNS resolution, explicitly supply the expected domain name using the sni_hostname request extension so HTTPX performs proper server name indication and certificate hostname validation.
Configure Secure TLS and Certificate Verification in HTTPX
Use when
Instantiating HTTPX clients or making HTTPS requests where TLS certificate verification, custom CA bundles, or IP-based SNI mapping must be securely enforced.
Secure rules
Rule 1: Configure SSL and TLS verification settings during client initialization rather than passing per-request SSL arguments.
When using HTTPX Client instances, pass TLS configuration parameters upon client instantiation. If distinct TLS configurations are needed, instantiate separate Client instances for each configuration because per-request SSL arguments are not supported.
Rule 2: Set the sni_hostname request extension when connecting directly to IP addresses for TLS verification.
When making HTTPS requests directly to an explicit IP address rather than a domain name, pass the expected server domain using the sni_hostname request extension so HTTPX can perform correct certificate hostname verification.
Rule 3: Use explicit ssl.SSLContext objects for custom certificates and client credentials.
Avoid passing deprecated string file paths or cert parameters directly. Build an explicit ssl.SSLContext using ssl.create_default_context() and load client certificate chains using ctx.load_cert_chain().
Rule 4: Explicitly inspect SSL environment variables when building custom SSLContext objects.
Because HTTPX does not automatically read SSL_CERT_FILE or SSL_CERT_DIR environment variables when custom contexts are used, explicitly retrieve and pass them to the ssl.SSLContext constructor.
Rule 5: Keep default TLS verification enabled and never disable it in production code.
Rely on HTTPX’s default SSL verification or supply an authenticated ssl.SSLContext object. Never pass verify=False in production code to prevent man-in-the-middle attacks.
Handle InvalidURL exceptions when parsing untrusted URLs
Approximately 187 tokens
Use when
Constructing HTTP requests from untrusted user input that may contain control characters or malformed syntax.
Secure rules
Rule 1: Catch httpx.InvalidURL exceptions when passing untrusted user input to request methods.
HTTPX’s URL parser explicitly rejects URLs containing ASCII non-printable control characters by raising httpx.InvalidURL. Wrap client request calls in a try-except block catching httpx.InvalidURL to ensure control-character injection attempts do not crash application logic.
Validate and parse untrusted URLs using HTTPX native parsing
Approximately 234 tokens
Use when
When processing external or untrusted URL strings to prevent parser differentials and invalid input interpretations before executing HTTP requests.
Secure rules
Rule 1: Instantiate httpx.URL and catch httpx.InvalidURL exceptions when handling external or untrusted URL strings.
Always parse user-supplied URL strings with httpx.URL and handle httpx.InvalidURL before executing requests to ensure strict WHATWG URL specification compliance and prevent parser differential vulnerabilities.
import httpxdef safe_fetch(user_supplied_url: str): try: url = httpx.URL(user_supplied_url) except httpx.InvalidURL: raise ValueError("Provided string is not a valid URL") if url.scheme not in ("http", "https"): raise ValueError("Unsupported URL scheme") with httpx.Client() as client: return client.get(url)
Configure explicit transport retries for transient connection errors
Approximately 201 tokens
Use when
Configuring HTTPX clients to handle connection failures and transient network timeouts safely using transport-level retries.
Secure rules
Rule 1: Configure explicit connection retries on httpx.HTTPTransport using the retries parameter.
Explicitly set the retries parameter on httpx.HTTPTransport to handle transient connection errors safely. Note that HTTPX transport retries only apply to httpx.ConnectError and httpx.ConnectTimeout, and do not automatically retry read/write errors or HTTP 5xx responses.
import httpxtransport = httpx.HTTPTransport(retries=3)with httpx.Client(transport=transport) as client: response = client.get("https://example.com")
Control Redirect Boundary Enforcement and Destination Validation
Approximately 166 tokens
Use when
Making HTTP requests where automatic redirects might cross network boundaries or expose sensitive credentials to untrusted origins.
Secure rules
Rule 1: Keep redirect following disabled or explicitly inspect redirect destinations before proceeding.
Maintain follow_redirects=False by default or strictly validate destination URLs before following HTTP redirects to prevent unintended credential leakage and SSRF.
import httpxresponse = httpx.get("http://example.com/", follow_redirects=False)if response.is_redirect: next_url = response.next_request.url # Perform boundary and scheme checks on next_url before making a request
Configure Explicit Timeouts and Connection Pool Limits for HTTP Requests
Approximately 448 tokens
Use when
When building HTTP client requests and managing connection transports to prevent thread starvation and resource exhaustion.
Secure rules
Rule 1: Always configure explicit non-zero timeouts and avoid using unbounded client settings.
Set explicit network and connection timeouts using httpx.Timeout or pass a direct numeric timeout value to prevent stalled connections from hanging indefinitely and consuming worker threads.
Rule 2: Define explicit connection pool limits on transports to prevent unbounded socket allocation.
Configure connection limits on HTTPTransport and AsyncHTTPTransport using custom Limits objects to protect system file descriptors and prevent socket exhaustion under heavy application traffic.
Stream Large Response Payloads and Enforce Size Limits
Use when
When downloading files or retrieving large response bodies to prevent out-of-memory crashes and denial of service.
Secure rules
Rule 1: Use response streaming to validate content size before reading payloads into memory.
Leverage httpx.stream() to inspect response content length or process incoming chunks incrementally, avoiding full memory allocation of large unbounded payloads.
import httpxMAX_ALLOWED_BYTES = 10 * 1024 * 1024with httpx.stream("GET", "https://example.com/large-file") as response: content_length = int(response.headers.get("Content-Length", 0)) if content_length < MAX_ALLOWED_BYTES: response.read() data = response.text else: raise ValueError("Response payload exceeds maximum allowed size.")
Prevent sensitive credential leaks across requests and redirects
Approximately 659 tokens
Use when
When developers configure client instances with default headers or custom authentication properties, or manage redirection behaviors.
Client-level default headers are automatically included on all outgoing requests sent through that client instance, which can accidentally leak secret tokens or API keys to unintended hosts. Use client.build_request() and explicitly remove sensitive credentials before dispatching requests to public or third-party URLs.
import httpxheaders = {"X-Api-Key": "secret-api-token", "X-Client-ID": "ABC123"}with httpx.Client(headers=headers) as client: request = client.build_request("GET", "https://public-api.example.com") del request.headers["X-Api-Key"] response = client.send(request)
Rule 2: Prevent sensitive header leaks during cross-origin redirects
While HTTPX automatically strips standard Authorization headers on cross-origin redirects, custom API key headers are not automatically purged. When follow_redirects is enabled, ensure custom sensitive headers are not forwarded to untrusted third-party redirect locations, or manage redirects explicitly.
import httpxwith httpx.Client(follow_redirects=False) as client: response = client.get( "https://api.example.com/data", headers={"X-Api-Key": "secret-token-123"} ) if response.is_redirect: target_url = response.headers["location"] if target_url.startswith("https://api.example.com/"): response = client.get(target_url, headers={"X-Api-Key": "secret-token-123"})
Redact and sanitize sensitive credentials in logs and telemetry outputs
Use when
When developers are logging HTTP request objects, response headers, URLs, or implementing request event hooks and diagnostics.
Secure rules
Rule 1: Rely on built-in credential obfuscation for URL representations
When logging httpx.URL instances containing embedded basic authentication credentials, use repr() or string formatting specifiers like %r to automatically mask passwords as [secure] instead of converting the URL to a string.
import httpxurl = httpx.URL("https://user:secret_pass@example.com/api")logger.info("Connecting to %r", url)
Rule 2: Sanitize custom credentials in request headers before logging
Because HTTPX automatically obfuscates standard authorization headers but does not mask custom sensitive headers like API keys or cookies, developers must explicitly filter or redact custom credential keys before recording header dictionaries in application logs or event hooks.
def log_request(request: httpx.Request) -> None: headers = dict(request.headers) if "authorization" in headers: headers["authorization"] = "[REDACTED]" logger.info("Outgoing request to %s with headers %s", request.url, headers)client = httpx.Client(event_hooks={"request": [log_request]})
Enforce Automated HTTP Status Validation Using Response Hooks
Approximately 218 tokens
Use when
When registering response event hooks on an HTTPX client to consistently enforce status code checking across all operations.
Secure rules
Rule 1: Register a response event hook that calls response.raise_for_status() to automatically enforce status code checks globally.
Use event hooks to guarantee that every client response triggers an httpx.HTTPStatusError on HTTP 4xx or 5xx responses, preventing application logic flaws or security control bypasses from unhandled error responses.
Isolate Client Instances and Configure Cookies at Initialization
Approximately 202 tokens
Use when
Managing session state and cookie persistence across requests when using httpx.Client.
Secure rules
Rule 1: Configure persistent session cookies during client instantiation to prevent cross-session leakage.
Supply persistent cookies upon client creation rather than passing per-request cookies or reusing a single client across multiple user sessions. Reusing a single client instance causes session cookies set by one server response to persist and automatically attach to subsequent requests, potentially leaking sensitive session tokens across distinct user contexts.
import httpx# Configure cookies at client initialization per sessiondef fetch_user_data(user_cookies: dict) -> httpx.Response: with httpx.Client(cookies=user_cookies) as client: return client.get("https://example.org/echo_cookies")