Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
abidlabs committed Oct 21, 2024
1 parent 84ed9bb commit 763ad7f
Showing 1 changed file with 59 additions and 2 deletions.
61 changes: 59 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ A small utility Python created to help developers protect their applications fro

It also implements mitigation for [DNS rebinding](https://en.wikipedia.org/wiki/DNS_rebinding) attacks.

## Why?

Server Side Request Forgery (SSRF) attacks can be particularly dangerous as they allow attackers to make arbitrary HTTP requests from your server, potentially accessing sensitive internal services that are normally unreachable from the internet. This could enable attackers to scan internal networks, access metadata services in cloud environments (like "AWS Instance Metadata Service"), or hit internal APIs - all while appearing to come from your trusted server. By validating URLs against public DNS servers and implementing protections against DNS rebinding, `safehttpx` helps prevent attackers from coercing your application into making requests to internal or otherwise restricted network resources.

## Usage

* **Basic Usage**
### Installation

```bash
$ pip install safehttpx
```

*Basic Usage**

```py
import safehttpx as sh
Expand All @@ -18,7 +28,54 @@ await sh.get("http://127.0.0.1")
>>> ValueError: Hostname 127.0.0.1 failed validation
```

## More info
**Note on Async Usage:**

The example snippets above will work in environments like IPython or Jupyter notebooks where an asyncio event loop is already running. For regular Python scripts, you'll need to explicitly create and run an asyncio event loop. Here's how you can structure your code to use `safehttpx` in a standard Python script:

```python
import asyncio
import safehttpx as sh

async def main():
response = await sh.get("https://huggingface.co")
print(response)

if __name__ == "__main__":
asyncio.run(main())
```

### Whitelisted Domains

You may want to whitelist certain domains from being validated. For example, if you are running code on a server that implements DNS splitting, then even public URLs may appear as internal URLs. You can whitelist domains like this:


```py
import safehttpx as sh

PUBLIC_HOSTNAME_WHITELIST = ["hf.co", "huggingface.co"]

await sh.get("https://huggingface.co", domain_whitelist=PUBLIC_HOSTNAME_WHITELIST)
>>> <Response [200 OK]>
```

### Custom Transports (Advanced)

If you know what you are doing, and what to pass in a custom instance of
`httpx.AsyncBaseTransport`, you can use the `_transport` parameter. Setting
this to `False` explicitly will use no secure transport (effectively
making `sh.get` equivalent to `httpx.AsyncClient.get()`).

```py
import safehttpx as sh

PUBLIC_HOSTNAME_WHITELIST = ["hf.co", "huggingface.co"]

await sh.get("https://huggingface.co", )
>>> <Response [200 OK]>
```


### More info

This library was created through joint efforts of Gradio (Hugging Face) and Trail Of Bits as a result of the Trail of Bits' audit of Gradio 5

0 comments on commit 763ad7f

Please sign in to comment.