hirara-core
Shared building blocks for Hirara agent tools. Small on purpose.
Why it exists
A tool that fetches an attacker-influenceable URL needs an SSRF perimeter. If
each tool hand-rolls its own, a new tool eventually ships without one — and
that is not hypothetical: the transcription tool added a URL-fetch path with a
bare httpx.get(url, follow_redirects=True) and no guard at all. This package
is the one guard every tool imports, so that hole can only be fixed — or
forgotten — in one place.
What's in it
| Symbol | Role |
|---|---|
resolve_target(url) |
Resolve-then-pin: validates the URL, checks every returned address, returns a Target pinned to one vetted IP. Raises BlockedURL. |
check_ip(ip) |
Is this address globally routable and not reserved? |
safe_download(url) |
A full redirect-safe, size-capped fetcher built on the guard — re-validates every hop, pins each request, streams and aborts at max_bytes. |
Usage
from hirara_core import safe_download, BlockedURL, DownloadError
try:
result = await safe_download(audio_url, max_bytes=25 * 1024 * 1024)
data = result.content # bytes, never larger than max_bytes
except BlockedURL as exc:
... # the URL is not allowed — a private IP, a bad scheme, a redirect inward
except DownloadError as exc:
... # it was allowed but did not work — bad status, transport error
BlockedURL (a security refusal) is kept distinct from DownloadError (an
ordinary failure) on purpose — a caller should treat "not allowed" and "did
not work" differently.
The two rules
- Resolve, then check every address, then pin. Rejecting only the first resolved address lets a resolver hand back one good IP and one bad one.
- Connect to the pinned IP, hostname in
Host+ SNI. Validating a name and letting the client resolve it again is a DNS-rebinding hole.
safe_download runs every redirect hop back through rule 1, so a public URL
that 302s to http://169.254.169.254/ is rejected at the hop.
Tests
pip install -e '.[dev]'
pytest -q
One case per real technique: metadata IPs, CGNAT, v4-mapped IPv6, 6to4, split-horizon DNS answers, credential-stuffed URLs, non-web ports, redirect-to- metadata, and the streaming byte cap.
Release files for hirara-core 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hirara_core-0.1.0.tar.gz | 9.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hirara_core-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.0 kB
Release files / hirara_core-0.1.0.tar.gz
| Download URL | hirara_core-0.1.0.tar.gz |
|---|---|
| Size | 9.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
518135fb6f45b5f823d0d95b9e39405d9d9c9c28a1918f0e8a5bbb070cbd5cbb
|
|
BLAKE2b-256 checksum How to use checksums |
e0be3c5935839b88c47cfd5a4bf378b8547938d94291979317fb0a34e084205f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.
Transparency logRelease files / hirara_core-0.1.0-py3-none-any.whl
| Download URL | hirara_core-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f0aa0ad241861ccadb66b07e03b0549224e1a65dc908881b0e04fbff54131867
|
|
BLAKE2b-256 checksum How to use checksums |
37d1a2f123491716059cdaa3188cf72a5335ce2eeefb5d3f6932addd729b1db0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.
Transparency log