bashkit

Networking & HTTP#

Bashkit’s HTTP builtins, curl, wget, and http, are the only way a script can reach the network, and they are default-deny. With no configuration, every outbound request is blocked. You opt in host by host with a NetworkAllowlist.

There is no DNS rebinding window, no automatic redirect following across hosts, and no access to private or cloud-metadata IP ranges. Networking is a sandbox boundary, not a convenience.

curl / wget http allowlist + private-IP block sign (opt-in) bot-auth send → blocked → request fails

Allowing hosts#

use bashkit::{Bash, NetworkAllowlist};

let allowlist = NetworkAllowlist::new()
    .allow("https://api.example.com")          // entire host
    .allow("https://cdn.example.com/assets/"); // path prefix

let mut bash = Bash::builder().network(allowlist).build();

bash.exec("curl https://api.example.com/v1/users").await?;

Pattern matching#

A request matches an allowlist entry when:

  • Scheme matches exactly, https is not http.
  • Host matches exactly, no wildcards, no implicit subdomains.
  • Port matches, defaults applied (443 for https, 80 for http).
  • Path is a prefix, the entry’s path must be a prefix of the request path.

This is literal-string matching by design: there is no DNS resolution at check time, which closes the DNS-spoofing and rebinding classes of attack (TM-NET-001/002).

Built-in SSRF protection#

Even for an allowed host, requests that resolve to private or reserved IP ranges are refused at connect time (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 including cloud metadata, CGNAT, and the IPv6 equivalents). This blocks SSRF via DNS rebinding even if an allowlisted hostname later resolves to an internal address (TM-NET-002/004/008). Override only when you fully control the environment:

let allowlist = NetworkAllowlist::new()
    .allow("http://localhost:8080")
    .block_private_ips(false); // dangerous — testing only

NetworkAllowlist::allow_all() disables host checks entirely. Use it only for fully trusted scripts.

curl data options#

Repeated -d/--data, --data-raw, --data-binary, and --data-urlencode values are joined with & in command-line order. -d @file removes CR/LF bytes, --data-binary @file preserves the file exactly, --data-raw treats a leading @ literally, and --data-urlencode supports both @file and name@file. Data requests default to application/x-www-form-urlencoded unless a content type was supplied.

curl -d 'page=1' --data-urlencode 'query=hello world' https://api.example.com/search
curl -G -d 'page=1' --data-urlencode 'query=hello world' https://api.example.com/search

The second form sends a GET and appends the ordered data to the existing query. The aggregate data is capped at 10 MB before dispatch; the URL allowlist still applies to the final request.

CLI#

The CLI keeps network access off unless you ask for it:

# Blocked by default
bashkit -c 'curl https://example.com'

# Unrestricted outbound (trusted scripts only)
bashkit --http-allow-all -c 'curl https://example.com'

Per-host allowlisting is a library-level concern (NetworkAllowlist); the CLI exposes the coarse --http-allow-all switch for trusted use.

Observing and rewriting requests#

HTTP requests flow through the same hooks pipeline as the rest of the interpreter, so a host can observe, rewrite, or cancel an outbound request before it leaves, useful for logging, header injection, or policy enforcement.

See also#