requests-hardened
is a library that overrides the default behaviors of the requests
library, and adds new security features.
The project is available on PyPI:
pip install requests-hardened
- SSRF Filters: blocks private and loopback IP ranges.
- HTTP Redirects: can be used safely alongside the SSRF filter feature.
- Proxy Support: proxies can be used in combination with SSRF Filters for a defense in depth.
- Handy Overrides of Defaults: allows to enforce secure defaults globally, such as to mitigate DoS attacks.
This library allows to override some default values from the requests
library
that can have a security impact:
Config.never_redirect = False
always reject HTTP redirectsConfig.default_timeout = (2, 10)
sets the default timeout value when no value orNone
is passedConfig.user_agent_override = None
optional config to overrideUser-Agent
header. When set toNone
,requests
library will set its default user-agent.
A SSRF IP filter can be used to reject HTTP(S) requests targeting private and loopback IP addresses.
Settings:
Config.ip_filter_enable
whether or not to filter the IP addressesip_filter_allow_loopback_ips
whether or not to allow loopback IP addresses
The SSRF IP filter's behavior with proxies are as follows:
Proxy's IP Address: does not block private and loopback IP addresses (no filtering). Instead, the filter assumes that the proxy URL is never tainted with untrusted user input.
Target IP Address (Tunneled HTTP Requests): by default, the tunneled requests are filtered for potential SSRF attacks.
Protocols Supported: SOCKS4, SOCKS5, HTTP, and HTTPS proxy server protocols are supported.
Note
We rely on the
requests
andurllib3
thus the list may change over time.Warning
For SOCKS4 and SOCKS5, you need to run
pip install requests[socks]
Example Usage:
from requests_hardened import Config, Manager
http_manager = Manager(
Config(
default_timeout=(2, 10),
never_redirect=False,
# Enable SSRF IP filter
ip_filter_enable=True,
ip_filter_allow_loopback_ips=False,
)
)
# List of proxies
proxies = {
"https": "socks5://127.0.0.1:8888",
"http": "socks5://127.0.0.1:8888",
}
# Sends the HTTP request using the proxy
resp = http_manager.send_request("GET", "https://example.com", proxies=proxies)
print(resp)
Note
For more details on using proxies with the requests
library, see the official
documentation.
from requests_hardened import Config, Manager
# Creates a global "manager" that can be used to create ``requests.Session``
# objects with hardening in place.
http_manager = Manager(
Config(
default_timeout=(2, 10),
never_redirect=False,
ip_filter_enable=True,
ip_filter_allow_loopback_ips=False,
user_agent_override=None
)
)
# Sends an HTTP request without re-using ``requests.Session``:
resp = http_manager.send_request("GET", "https://example.com")
print(resp)
# Sends HTTP requests with reusable ``requests.Session``:
with http_manager.get_session() as sess:
sess.request("GET", "https://example.com")
sess.request("POST", "https://example.com", json={"foo": "bar"})