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 = Falsealways reject HTTP redirectsConfig.default_timeout = (2, 10)sets the default timeout value when no value orNoneis passedConfig.user_agent_override = Noneoptional config to overrideUser-Agentheader. When set toNone,requestslibrary 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_enablewhether or not to filter the IP addressesip_filter_allow_loopback_ipswhether or not to allow loopback IP addresses
The SSRF IP filter's behavior with proxies are as follows:
Proxy's IP Address: no IP filtering is performed against proxy URLs, therefore private IP addresses, loopback addresses, and other reserved IP ranges (such as 100.64.0.0/10) are not blocked when provided as the proxy URL. 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
requestsandurllib3thus 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 (no IP filtering as described above under 'Proxy's IP Address')
proxies = {
"https": "socks5://127.0.0.1:8888",
"http": "socks5://127.0.0.1:8888",
}
# Sends the HTTP request using the proxy (IP filtering is performed against
# the `https://example.com` URL)
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"})