Keyboard shortcuts

Press โ† or โ†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

httpjail

Crates.io CI

A cross-platform tool for monitoring and restricting HTTP/HTTPS requests from processes using network isolation and transparent proxy interception.

Warning: httpjail is experimental and offers no API or CLI compatibility guarantees.

What is httpjail?

httpjail provides process-level network isolation and HTTP request control for applications. It acts as a transparent proxy that intercepts all HTTP/HTTPS traffic from a process and its children, allowing you to:

  • Monitor all outgoing HTTP/HTTPS requests
  • Block requests based on customizable rules
  • Log network activity for auditing
  • Prevent data exfiltration through DNS
  • Isolate processes in restricted network environments

Key Features

  • ๐Ÿ”’ Process-level network isolation - Isolate processes in restricted network environments
  • ๐ŸŒ HTTP/HTTPS interception - Transparent proxy with TLS certificate injection
  • ๐Ÿ›ก๏ธ DNS exfiltration protection - Prevents data leakage through DNS queries
  • ๐Ÿ”ง Script-based evaluation - Custom request evaluation logic via external scripts
  • ๐Ÿš€ JavaScript evaluation - Fast, secure request filtering using V8 JavaScript engine
  • ๐Ÿ“ Request logging - Monitor and log all HTTP/HTTPS requests
  • โ›” Default deny - Requests are blocked unless explicitly allowed
  • ๐Ÿ–ฅ๏ธ Cross-platform - Native support for Linux and macOS
  • โšก Zero configuration - Works out of the box with sensible defaults

Use Cases

  • Security auditing - Monitor what network resources an application accesses
  • Compliance - Ensure applications only communicate with approved endpoints
  • Development - Test applications with restricted network access
  • CI/CD - Control and log network access during builds and tests
  • Privacy - Prevent applications from phoning home or leaking data

How It Works

httpjail creates an isolated network environment for your process:

  1. Network Isolation: On Linux, creates a network namespace; on macOS, uses environment variables
  2. Transparent Proxy: All HTTP/HTTPS traffic is redirected through httpjail's proxy
  3. Rule Evaluation: Each request is evaluated against your configured rules
  4. Action: Requests are either allowed through or blocked based on the evaluation
graph LR
    A[Application] -->|HTTP/HTTPS Request| B[httpjail Proxy]
    B --> C{Rule Engine}
    C -->|Allow| D[Forward to Target]
    C -->|Deny| E[Return 403]
    D --> F[Target Server]
    F -->|Response| B
    B -->|Response| A
    E -->|Error| A

Getting Started

The simplest way to use httpjail is with JavaScript rules:

# Allow only requests to github.com
httpjail --js "r.host === 'github.com'" -- curl https://github.com

# Block everything (default behavior)
httpjail -- curl https://example.com

For more examples and detailed usage, see the Quick Start guide.

Installation

httpjail can be installed in several ways depending on your needs and platform.

Cargo

If you have Rust installed, you can install httpjail using Cargo:

# optional: brew install rust
cargo install httpjail

This will compile httpjail from source and install it to your Cargo bin directory (usually ~/.cargo/bin/).

Pre-built Binaries

The easiest way to install httpjail is to download a pre-built binary from the releases page.

Linux

# Download the latest release (example for Linux x86_64)
curl -L https://github.com/coder/httpjail/releases/latest/download/httpjail-linux-amd64 -o httpjail
chmod +x httpjail
sudo mv httpjail /usr/local/bin/

macOS

# Download the latest release (example for macOS arm64)
curl -L https://github.com/coder/httpjail/releases/latest/download/httpjail-darwin-arm64 -o httpjail
chmod +x httpjail
sudo mv httpjail /usr/local/bin/

Build from Source

For development or to get the latest unreleased features:

# Clone the repository
git clone https://github.com/coder/httpjail.git
cd httpjail

# Build in release mode
cargo build --release

# The binary will be at target/release/httpjail
sudo cp target/release/httpjail /usr/local/bin/

Fast Development Builds

For faster builds during development:

cargo build --profile fast

This profile provides reasonable performance with significantly faster build times.

System Requirements

Linux

  • Linux kernel 3.8+ (for network namespaces)
  • Root privileges (for network namespace creation)
  • iptables (for traffic redirection)

macOS

  • macOS 10.15+ (Catalina or later)
  • No special privileges required (uses weak mode)

Verify Installation

After installation, verify httpjail is working:

# Check version
httpjail --version

# Test with a simple command
httpjail --js "false" -- curl https://example.com
# Should block the request

Trust the CA Certificate (Optional)

For HTTPS interception to work smoothly, you may want to trust httpjail's CA certificate:

# Install the CA certificate to system trust store
httpjail trust --install

# Remove the CA certificate
httpjail trust --uninstall

This is especially important on macOS for applications that use the system keychain (like Go programs).

Next Steps

Now that you have httpjail installed, check out the Quick Start guide to learn how to use it.

Quick Start

This guide will help you get started with httpjail quickly.

Note: By default, httpjail denies all network requests. You must provide rules to allow traffic.

Basic Usage

The basic syntax for httpjail is:

httpjail [OPTIONS] -- <COMMAND> [ARGS...]

Examples

Allow All Requests

# Allow all HTTP/HTTPS requests (not recommended for production)
httpjail --js "true" -- curl https://example.com

Allow Specific Hosts

# Allow only requests to github.com
httpjail --js "r.host === 'github.com'" -- git clone https://github.com/user/repo.git

# Allow multiple hosts
httpjail --js "['github.com', 'api.github.com'].includes(r.host)" -- your-app

# Allow using regex
httpjail --js "/^.*\\.example\\.com$/.test(r.host)" -- npm install

Filter by Method

# Only allow GET requests
httpjail --js "r.method === 'GET'" -- curl https://api.example.com

# Allow GET and POST
httpjail --js "['GET', 'POST'].includes(r.method)" -- your-app

Complex Rules

# Allow only GET requests to api.example.com
httpjail --js "r.host === 'api.example.com' && r.method === 'GET'" -- curl https://api.example.com/data

# Allow specific path patterns
httpjail --js "r.host === 'api.github.com' && r.path.startsWith('/repos/')" -- gh repo list

Using Rule Files

For complex rules, use a JavaScript file:

// rules.js
// Allow GitHub API and npmjs.org
const allowedHosts = [
  'api.github.com',
  'github.com',
  'registry.npmjs.org',
  'registry.yarnpkg.com'
];

const isAllowed = allowedHosts.some(host => 
  r.host === host || r.host.endsWith('.' + host)
);

// Result (must be a boolean expression)
isAllowed && r.method !== 'DELETE';
httpjail --js-file rules.js -- npm install

Request Logging

Monitor what requests are being made:

# Log to stdout
httpjail --request-log /dev/stdout --js "true" -- your-app

# Log to file
httpjail --request-log requests.log --js "true" -- npm install

# Log format: <timestamp> <+/-> <METHOD> <URL>
# + means allowed, - means blocked

Shell Script Rules

Use a shell script for complex logic:

#!/bin/bash
# check.sh
if [[ "$HTTPJAIL_HOST" == "github.com" ]]; then
  exit 0  # Allow
else
  echo "Blocked: $HTTPJAIL_HOST is not allowed"
  exit 1  # Block
fi
chmod +x check.sh
httpjail --sh ./check.sh -- git clone https://github.com/user/repo.git

Common Patterns

Development Environment

# Allow common development services
httpjail --js "
  ['localhost', '127.0.0.1', '::1'].includes(r.host) ||
  r.host.endsWith('.local') ||
  r.host === 'registry.npmjs.org'
" -- npm run dev

CI/CD Pipeline

# Strict rules for CI
httpjail --js-file ci-rules.js --request-log build-requests.log -- make build

Package Installation

# Allow package registries only
httpjail --js "
  ['registry.npmjs.org', 'registry.yarnpkg.com', 'pypi.org', 'crates.io']
    .some(h => r.host === h || r.host.endsWith('.' + h))
" -- npm install

Debugging

When requests are blocked, httpjail returns a 403 Forbidden response with details:

HTTP/1.1 403 Forbidden
Content-Type: text/plain

httpjail: Blocked GET https://blocked.example.com/

Use --request-log to see all requests and understand what's being blocked:

httpjail --request-log /dev/stderr --js "false" -- curl https://example.com
# Will show: 2024-01-01 12:00:00 - GET https://example.com/

Next Steps

Configuration

httpjail's behavior can be configured through command-line options, environment variables, and configuration files. This page provides an overview of how these work together.

Configuration Hierarchy

httpjail follows a simple configuration hierarchy:

  1. Command-line options - Highest priority, override everything
  2. Environment variables - Set by httpjail for the jailed process

Key Configuration Areas

Rule Engine Selection

Choose how requests are evaluated:

  • JavaScript (--js or --js-file) - Fast, sandboxed evaluation
  • Shell Script (--sh) - System integration, external tools
  • Line Processor (--proc) - Stateful, streaming evaluation

Only one rule engine can be active at a time. See Rule Engines for detailed comparison.

Network Mode

Control the isolation level:

  • Strong mode (default on Linux) - Full network namespace isolation
  • Weak mode (--weak) - Environment variables only, no isolation
  • Server mode (--server) - Run as standalone proxy server

Logging and Monitoring

Track what's happening:

  • Request logging (--request-log) - Log all HTTP requests
  • Debug output (RUST_LOG=debug) - Detailed operational logs
  • Process output - Captured from the jailed command

See Request Logging for details.

Common Configurations

Development Environment

# Allow localhost and common dev services
httpjail --js "['localhost', '127.0.0.1'].includes(r.host)" \
         --request-log /dev/stdout \
         -- npm run dev

CI/CD Pipeline

# Strict allow-list for builds
httpjail --js-file ci-rules.js \
         --request-log build-network.log \
         --timeout 600 \
         -- make build

Production Service

# Stateful filtering with monitoring
httpjail --proc ./rate-limiter.py \
         --request-log /var/log/httpjail/requests.log \
         -- ./api-server

Environment Variables

Set by httpjail

These are automatically set in the jailed process:

VariableDescriptionExample
HTTP_PROXYHTTP proxy addresshttp://127.0.0.1:34567
HTTPS_PROXYHTTPS proxy addresshttp://127.0.0.1:34567
SSL_CERT_FILECA certificate path/tmp/httpjail-ca.pem
SSL_CERT_DIRCA certificate directory/tmp/httpjail-certs/
NO_PROXYBypass proxy for these hostslocalhost,127.0.0.1

Controlling httpjail

These affect httpjail's behavior:

VariableDescriptionExample
RUST_LOGLogging leveldebug, info, warn, error
HTTPJAIL_CA_CERTCustom CA certificate path/etc/pki/custom-ca.pem

Platform-Specific Configuration

Linux

  • Uses network namespaces for strong isolation
  • Requires root/sudo for namespace operations
  • iptables rules for traffic redirection
  • Supports all network modes

macOS

  • Limited to weak mode (environment variables)
  • No root required for standard operation
  • Certificate trust via Keychain Access
  • Some apps may ignore proxy variables

See Platform Support for detailed information.

Troubleshooting Configuration

Rules not matching

# Debug rule evaluation
RUST_LOG=debug httpjail --js "r.host === 'example.com'" -- curl https://example.com

# Log all requests to see what's being evaluated
httpjail --request-log /dev/stderr --js "false" -- your-app

Environment variables not working

# Check what's set in the jail
httpjail --js "true" -- env | grep -E "(HTTP|PROXY|SSL)"

# Verify proxy is listening
httpjail --js "true" -- curl -I http://127.0.0.1:$PROXY_PORT

Certificate issues

# Trust the CA certificate
httpjail trust --install

# Check certificate details
openssl x509 -in ~/.config/httpjail/ca-cert.pem -text -noout

Next Steps

Rule Engines

httpjail provides three different rule engines for evaluating HTTP requests. Each has different trade-offs in terms of performance, flexibility, and ease of use.

Engine Comparison

FeatureJavaScript (V8)Shell ScriptLine Processor
Performance
Per-Request Latency550ยตs-1.3ms700ยตs-1.6ms70-90ยตs
Capabilities
Stateful ProcessingโŒโœ…โœ…
External Tool AccessโŒโœ…โœ…
Language ChoiceJS onlyAnyAny
Sandboxed Executionโœ…โŒDepends
Development ComplexityEasyEasyModerate

Performance Note: Latency measurements are from benchmarks on modern hardware. JavaScript (V8) creates a new isolate per request for safety. Line processor maintains a persistent process, providing the best performance for high-throughput scenarios.

Examples

Simple Host Filtering

All three engines can handle basic filtering:

JavaScript:

httpjail --js "r.host === 'github.com'" -- command

Shell Script:

#!/bin/bash
[[ "$HTTPJAIL_HOST" == "github.com" ]] && exit 0 || exit 1

Line Processor:

#!/usr/bin/env python3
import sys, json
for line in sys.stdin:
    req = json.loads(line)
    print("true" if req["host"] == "github.com" else "false")

Complex Logic

For complex scenarios, consider the implementation complexity:

JavaScript - Limited to expression evaluation:

// Complex but still performant
const allowed = ["api.example.com", "cdn.example.com"];
allowed.includes(r.host) && r.method === "GET" && r.path.startsWith("/v1/");

Shell Script - Can use any tool but slower:

#!/bin/bash
# Check against database, but spawns process per request
psql -c "SELECT allowed FROM rules WHERE host='$HTTPJAIL_HOST'" | grep -q true

Line Processor - Best for complex stateful logic:

#!/usr/bin/env python3
# Maintains state, handles thousands of requests efficiently
import sys, json, time
from collections import defaultdict

rate_limits = defaultdict(lambda: {"count": 0, "reset": time.time() + 60})

for line in sys.stdin:
    req = json.loads(line)
    host_limit = rate_limits[req["host"]]

    if time.time() > host_limit["reset"]:
        host_limit["count"] = 0
        host_limit["reset"] = time.time() + 60

    if host_limit["count"] < 100:  # 100 requests per minute
        host_limit["count"] += 1
        print("true")
    else:
        print("false")
    sys.stdout.flush()

Next Steps

JavaScript Rules

Fast, sandboxed request evaluation using the V8 JavaScript engine.

The Request Object

Your JavaScript code receives a r object with these properties:

  • r.url - Full URL
  • r.method - HTTP method (GET, POST, etc.)
  • r.host - Hostname
  • r.scheme - URL scheme (http/https)
  • r.path - URL path

Basic Usage

Inline Rules

# Allow specific host
httpjail --js "r.host === 'github.com'" -- command

# Multiple conditions
httpjail --js "r.host === 'api.example.com' && r.method === 'GET'" -- command

# Using arrays
httpjail --js "['GET', 'POST'].includes(r.method)" -- command

File-based Rules

// rules.js
const allowedHosts = ['github.com', 'api.github.com'];

// The last expression is the result
allowedHosts.includes(r.host);
httpjail --js-file rules.js -- command

Response Format

Response FormatMeaning
trueAllow the request
falseDeny the request
{allow: true}Allow (object form)
{allow: false}Deny (object form)
{
allow: false,
deny_message: "Access denied"
}
Deny with custom message
{deny_message: "Blocked"}Deny (message implies deny)
{
allow: {
max_tx_bytes: 1024
}
}
Allow with request body limiting

Examples:

// Simple boolean
true  // Allow
false // Deny

// With custom deny message (needs parentheses in inline expressions)
({allow: false, deny_message: "Social media blocked"})

// Conditional with message
r.host === 'facebook.com' ? {deny_message: 'Social media blocked'} : true

// Limit request upload size to 1KB (headers + body)
({allow: {max_tx_bytes: 1024}})

Common Patterns

Domain Allowlisting

const allowed = ['example.com', 'api.example.com'];
allowed.includes(r.host)

Subdomain Matching

r.host === 'example.com' || r.host.endsWith('.example.com')

Path-based Rules

r.host === 'api.example.com' && r.path.startsWith('/v1/public/')

Method Restrictions

['GET', 'HEAD', 'OPTIONS'].includes(r.method)

Host Whitelist

// Simple host whitelist
const allowedHosts = [
  'github.com',
  'api.github.com',
  'raw.githubusercontent.com',
  'codeload.github.com'
];

allowedHosts.includes(r.host)

Host + Method Whitelist

// Allow specific methods only for certain hosts
const rules = [
  {host: 'api.github.com', methods: ['GET', 'POST']},
  {host: 'github.com', methods: ['GET']},
  {host: 'uploads.github.com', methods: ['POST', 'PUT']}
];

rules.some(rule => 
  rule.host === r.host && rule.methods.includes(r.method)
)

Regexp Matching on Method + URL

// Whitelist patterns for METHOD + URL combinations
const patterns = [
  /^GET api\.github\.com\/repos\/.+/,
  /^POST api\.example\.com\/v[12]\/.*/,
  /^(GET|HEAD) .*\.cdn\.example\.com\/.*\.(jpg|png|gif)/
];

// Build request string using host and path for simpler patterns
const requestString = `${r.method} ${r.host}${r.path}`;
patterns.some(pattern => pattern.test(requestString))

When to Use

Best for:

  • Simple host/path filtering
  • Quick prototyping
  • Untrusted rule sources (sandboxed)

Avoid for:

  • Stateful processing (use line processor)
  • External integrations (use shell or line processor)

Shell Script Rule Engine

Execute external scripts or programs to evaluate HTTP requests. Use any language or integrate with external systems.

How It Works

With --sh, httpjail executes your script for each request, passing details through environment variables. Exit code 0 allows the request, non-zero denies it.

Basic Usage

# Use a shell script for evaluation
httpjail --sh "./policy.sh" -- curl https://api.example.com

# Use an inline command
httpjail --sh "exit 0" -- curl https://example.com  # Allow all

# Use any executable
httpjail --sh "/usr/local/bin/my-policy-checker" -- ./my-app

Environment Variables

Your script receives the following environment variables:

VariableDescriptionExample
HTTPJAIL_URLComplete request URLhttps://api.github.com/repos
HTTPJAIL_METHODHTTP methodGET, POST, PUT, etc.
HTTPJAIL_SCHEMEURL schemehttp or https
HTTPJAIL_HOSTHostname from URLapi.github.com
HTTPJAIL_PATHURL path/repos
HTTPJAIL_REQUESTER_IPIP of the requesting process127.0.0.1

Exit Codes and Output

  • Exit code 0: Request is allowed
  • Any non-zero exit code: Request is denied
  • stdout: Becomes the response body for denied requests (useful for custom error messages)
  • stderr: Logged for debugging (use RUST_LOG=debug to see)

Examples

Simple Allow/Deny Script

#!/bin/sh
# allow-github.sh - Only allow GitHub API requests

case "$HTTPJAIL_HOST" in
    api.github.com|github.com)
        exit 0  # Allow
        ;;
    *)
        echo "Only GitHub requests allowed"
        exit 1  # Deny
        ;;
esac

Domain Allowlist

Command:

httpjail --sh "./rules.sh" -- curl https://api.github.com/repos

In whitelist.txt:

api.github.com
github.com
raw.githubusercontent.com
api.gitlab.com
gitlab.com

In rules.sh:

#!/bin/sh
# Check if host is in whitelist file

# Read whitelist file (one domain per line)
WHITELIST_FILE="./whitelist.txt"

# Check if whitelist file exists
if [ ! -f "$WHITELIST_FILE" ]; then
    echo "Whitelist file not found: $WHITELIST_FILE"
    exit 1
fi

# Check if current host is in the whitelist (exact match)
if grep -Fxq "$HTTPJAIL_HOST" "$WHITELIST_FILE"; then
    exit 0  # Allow
else
    echo "Host $HTTPJAIL_HOST not in whitelist"
    exit 1  # Deny
fi

Method-Based Restrictions

#!/bin/sh
# read-only.sh - Only allow safe HTTP methods

case "$HTTPJAIL_METHOD" in
    GET|HEAD|OPTIONS)
        exit 0
        ;;
    *)
        echo "Method $HTTPJAIL_METHOD not allowed (read-only mode)"
        exit 1
        ;;
esac

Using Other Languages

#!/usr/bin/env python3
import os, sys

if os.environ.get('HTTPJAIL_HOST') == 'api.github.com':
    sys.exit(0)  # Allow
else:
    print("Only GitHub API allowed")
    sys.exit(1)  # Deny

Script vs Command

httpjail determines how to execute your script:

  • Contains spaces: Executed as sh -c "your command"
  • No spaces: Executed directly as a binary/script
# These are equivalent:
httpjail --sh "exit 0" -- curl example.com
httpjail --sh "./my-script.sh" -- curl example.com

# But this runs the binary directly (more efficient):
httpjail --sh "/usr/local/bin/policy-check" -- curl example.com

Error Handling

Script Not Found

$ httpjail --sh "./nonexistent.sh" -- curl example.com
# Error: Script execution failed: No such file or directory

Script Not Executable

$ httpjail --sh "./policy.sh" -- curl example.com
# Error: Script execution failed: Permission denied
# Fix: chmod +x ./policy.sh

Script Timeout

Scripts that run longer than 30 seconds are automatically terminated:

#!/bin/sh
# This will timeout
sleep 60
exit 0

When to Use Shell Scripts

Best for:

  • External integrations (databases, APIs)
  • Reusing existing scripts/tools
  • Any programming language

Avoid for:

  • High-throughput scenarios (use line processor mode)
  • Simple logic (use JavaScript)

For high-throughput scenarios, consider the Line Processor mode which maintains a single process.

Line Processor

Stream requests to a long-running process for stateful, high-performance filtering.

How It Works

  1. httpjail spawns your processor once at startup
  2. For each HTTP request, httpjail sends a JSON line to the processor's stdin
  3. The processor evaluates and responds with "true" or "false"
  4. The process continues running until httpjail exits

Protocol

Request Format

Each request is sent as a single JSON line:

{
  "url": "https://example.com/api",
  "method": "GET",
  "host": "example.com",
  "scheme": "https",
  "path": "/api"
}

Response Format

Your processor must respond with one line per request.

Response FormatMeaning
trueAllow the request
falseDeny the request
{allow: true}Allow (object form)
{allow: false}Deny (object form)
{
allow: false,
deny_message: "Access denied"
}
Deny with custom message
{deny_message: "Blocked"}Deny (message implies deny)
{
allow: {
max_tx_bytes: 1024
}
}
Allow with request body limiting

Additional:

  • Boolean strings: "true" (allow) or "false" (deny) - same as boolean
  • Any other text: Treated as deny with that text as the message (e.g., "Access denied" becomes a deny with message "Access denied")

Command Line Usage

# Use a Python script as processor
httpjail --proc ./filter.py -- your-command

# Use any executable
httpjail --proc "/usr/bin/python3 -u filter.py" -- your-command

# Pass arguments to the processor
httpjail --proc "./filter.sh --strict" -- your-command

Examples

Python Example

#!/usr/bin/env python3
import sys, json

allowed_hosts = {'github.com', 'api.github.com'}
upload_hosts = {'uploads.example.com'}

for line in sys.stdin:
    try:
        req = json.loads(line)
        if req['host'] in allowed_hosts:
            print("true")
        elif req['host'] in upload_hosts:
            # Limit upload endpoints to 1KB requests
            response = {"allow": {"max_tx_bytes": 1024}}
            print(json.dumps(response))
        else:
            # Can return JSON for custom messages
            response = {"allow": False, "deny_message": f"{req['host']} not allowed"}
            print(json.dumps(response))
    except:
        print("Invalid request")  # Any non-boolean text becomes deny message
    sys.stdout.flush()  # Ensure immediate response

Bash Example

#!/bin/bash

while IFS= read -r line; do
    host=$(echo "$line" | jq -r .host)

    if [[ "$host" == *.github.com ]]; then
        echo "true"
    else
        echo "false"
    fi
done

Important Notes

  • Flush output after each response (sys.stdout.flush() in Python, automatic in bash)
  • Handle errors gracefully - always respond with allow or deny
  • Use stderr for debugging - stdout is reserved for responses

Best for

  • High-throughput scenarios
  • Stateful processing (caching, rate limiting)
  • Complex logic requiring external libraries

Platform Support

httpjail works differently on each platform due to OS-specific networking capabilities.

Platform Comparison

FeatureLinuxmacOSWindows
Traffic isolationโœ… Namespaces + nftablesโš ๏ธ Env vars only๐Ÿšง Planned
TLS interceptionโœ… Transparentโœ… Via proxy settings๐Ÿšง Planned
Sudo requiredโš ๏ธ Yesโœ… No๐Ÿšง
Force all trafficโœ… YesโŒ Apps must cooperate๐Ÿšง

Linux

Full network isolation using namespaces and nftables.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 httpjail Process                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  1. Create network namespace                    โ”‚
โ”‚  2. Setup nftables rules                        โ”‚
โ”‚  3. Start embedded proxy + DNS server           โ”‚
โ”‚  4. Export CA trust env vars                    โ”‚
โ”‚  5. Execute target process in namespace         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              Target Process                     โ”‚
โ”‚  โ€ข Isolated in network namespace                โ”‚
โ”‚  โ€ข User dropped to $SUDO_USER                   โ”‚
โ”‚  โ€ข All HTTP/HTTPS โ†’ local proxy                 โ”‚
โ”‚  โ€ข All DNS queries โ†’ dummy resolver (6.6.6.6)   โ”‚
โ”‚  โ€ข CA cert trusted via env vars                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Prerequisites

  • Linux kernel 3.8+ (network namespace support)
  • nftables (nft command)
  • libssl-dev (for TLS)
  • sudo access (for namespace creation)

How It Works

  • Creates isolated network namespace
  • Uses nftables to redirect all HTTP/HTTPS traffic
  • Intercepts DNS queries (returns 6.6.6.6 to prevent exfiltration)
  • Transparent TLS interception with per-host certificates

Usage

# Strong mode (default) - full isolation
sudo httpjail --js "r.host === 'github.com'" -- curl https://api.github.com

# Weak mode - environment variables only (no sudo)
httpjail --weak --js "r.host === 'github.com'" -- curl https://api.github.com

macOS

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 httpjail Process                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  1. Start HTTP/HTTPS proxy servers              โ”‚
โ”‚  2. Set HTTP_PROXY/HTTPS_PROXY env vars         โ”‚
โ”‚  3. Generate/load CA certificate                โ”‚
โ”‚  4. Execute target with proxy environment       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              Target Process                     โ”‚
โ”‚  โ€ข HTTP_PROXY/HTTPS_PROXY environment vars      โ”‚
โ”‚  โ€ข Applications must respect proxy settings     โ”‚
โ”‚  โ€ข CA cert via environment variables            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Note: Due to macOS PF (Packet Filter) limitations, httpjail uses environment-based proxy configuration on macOS. PF translation rules (such as rdr and route-to) cannot match on user or group, making transparent traffic interception impossible. As a result, httpjail operates in "weak mode" on macOS, relying on applications to respect the HTTP_PROXY and HTTPS_PROXY environment variables. Most command-line tools and modern applications respect these settings, but some may bypass them. See also https://github.com/coder/httpjail/issues/7.

Prerequisites

  • No special permissions required
  • Applications must respect proxy environment variables

Certificate Trust

httpjail generates a unique CA certificate for TLS interception:

# Check if CA is trusted
httpjail trust

# Install CA to user keychain (prompts for password)
httpjail trust --install

# Remove CA from keychain
httpjail trust --remove

Note: Most CLI tools respect the SSL_CERT_FILE environment variable that httpjail sets automatically. Go programs require the CA in the keychain.

How It Works

  • Sets HTTP_PROXY and HTTPS_PROXY environment variables
  • Applications must voluntarily use these proxy settings
  • Cannot force traffic from non-cooperating applications
  • DNS queries are not intercepted

Usage

# Always runs in weak mode on macOS (no sudo needed)
httpjail --js "r.host === 'github.com'" -- curl https://api.github.com

Windows

Support is planned but not yet implemented.

Mode Selection

httpjail automatically selects the appropriate mode:

  • Linux: Strong mode by default, use --weak to force environment-only mode
  • macOS: Always weak mode (environment variables)
  • Windows: Not yet supported

Environment Variables

httpjail sets these variables for the child process to trust the CA certificate:

  • SSL_CERT_FILE / SSL_CERT_DIR - OpenSSL and most tools
  • CURL_CA_BUNDLE - curl
  • REQUESTS_CA_BUNDLE - Python requests
  • NODE_EXTRA_CA_CERTS - Node.js
  • CARGO_HTTP_CAINFO - Cargo
  • GIT_SSL_CAINFO - Git

Request Logging

Log all HTTP/HTTPS requests to a file for auditing, debugging, or analysis.

Basic Usage

httpjail --request-log requests.log --js "true" -- npm install

Log Format

Each request is logged on a single line:

<timestamp> <+/-> <METHOD> <URL>
  • + indicates allowed requests
  • - indicates blocked requests

Example Output

2025-09-22T14:23:45.123Z + GET https://registry.npmjs.org/react
2025-09-22T14:23:45.234Z + GET https://registry.npmjs.org/react-dom
2025-09-22T14:23:45.345Z - POST https://analytics.example.com/track

Example: BigQuery Integration

Achieve more advanced logging with the line processor rule engine (--proc). Here's an example of how to log to every request to BigQuery:

#!/bin/bash
# log-to-bigquery.sh

while read -r line; do
    # Create BigQuery insert payload
    echo "$line" | jq -c '{
        rows: [{
            insertId: (now | tostring),
            json: . + {timestamp: (now | todate)}
        }]
    }' | bq insert my-project:httpjail_logs.requests
    
    # Allow all requests
    echo "true"
done

Usage:

httpjail --proc ./log-to-bigquery.sh --request-log local-backup.log -- your-app

This example shows real-time logging where each request is immediately inserted into BigQuery. Note: bq insert is intended for testing only - for production use BigQuery client libraries.

Request Body Limiting

The max_tx_bytes feature allows you to limit the total size of HTTP requests sent to upstream servers.

This is primarily designed for mitigating code exfiltration attacks through covert channels.

Size Calculation

The max_tx_bytes limit applies to complete HTTP requests, including:

  1. Request line: METHOD /path HTTP/1.1\r\n
  2. Headers: Each header as Name: Value\r\n
  3. Header separator: Final \r\n between headers and body
  4. Body: Request body bytes

Response Format

To enable request body limiting, return an object with max_tx_bytes in your rule response:

// JavaScript engine
{allow: {max_tx_bytes: 1024}}  // Limit to 1KB total request size
// Line processor engine
{"allow": {"max_tx_bytes": 1024}}

Note: The max_tx_bytes feature is only available in the JavaScript (--js) and Line Processor (--proc) engines, not in Shell scripts.

Behavior

The limiting behavior depends on whether the request includes a Content-Length header:

With Content-Length Header

When the request includes a Content-Length header (most standard HTTP clients):

  1. Early Detection: httpjail calculates the total request size
  2. Immediate Rejection: If it exceeds max_tx_bytes, the client receives a 413 Payload Too Large error immediately
  3. No Upstream Contact: The upstream server is never contacted, preventing unnecessary load
  4. Clear Feedback: The error message indicates the actual size and limit

Example error response:

HTTP/1.1 413 Payload Too Large
Content-Type: text/plain

Request body size (5000 bytes) exceeds maximum allowed (1024 bytes)

Without Content-Length Header

When the request uses chunked encoding or doesn't include Content-Length:

  1. Stream Truncation: The request body is truncated at the limit during streaming
  2. Upstream Receives Partial: The upstream server receives exactly max_tx_bytes total bytes (url + headers + truncated body)
  3. Connection Closes: The connection terminates after reaching the limit

Examples

JavaScript Engine - Upload Endpoint Limiting

// Limit upload endpoints to 1KB total request size
const uploadHosts = ['uploads.example.com', 'upload.github.com'];

uploadHosts.includes(r.host)
  ? {allow: {max_tx_bytes: 1024}}
  : r.host.endsWith('.example.com')

Line Processor Engine - Python Example

#!/usr/bin/env python3
import sys, json

upload_hosts = {'uploads.example.com', 'data.api.com'}

for line in sys.stdin:
    try:
        req = json.loads(line)
        if req['host'] in upload_hosts:
            # Limit upload endpoints to 1KB requests
            # Returns 413 error if Content-Length exceeds limit
            # Truncates body if no Content-Length header
            response = {"allow": {"max_tx_bytes": 1024}}
            print(json.dumps(response))
        elif req['host'].endswith('.example.com'):
            print("true")
        else:
            print("false")
    except:
        print("false")
    sys.stdout.flush()

Use Cases

1. Limiting File Uploads

Prevent users from uploading large files to specific endpoints:

// JavaScript engine
const uploadPaths = ['/upload', '/api/files'];
uploadPaths.some(path => r.path.startsWith(path))
  ? {allow: {max_tx_bytes: 10485760}}  // 10MB limit
  : true

2. API Cost Control

Limit request sizes to metered APIs to prevent unexpected costs:

// JavaScript engine
r.host === 'api.expensive-service.com'
  ? {allow: {max_tx_bytes: 1024}}  // 1KB limit for expensive API
  : true

3. Data Exfiltration Prevention

Prevent large data uploads that might indicate data exfiltration:

// JavaScript engine
const externalHosts = ['pastebin.com', 'transfer.sh', 'file.io'];
externalHosts.some(host => r.host.includes(host))
  ? {allow: {max_tx_bytes: 4096}}  // 4KB limit for paste sites
  : true

Limitations

  • Shell scripts: The max_tx_bytes feature is not available when using shell script rules (--shell)
  • HTTP wire format: The byte count is based on HTTP wire format, not just the body size
  • Partial uploads: When truncating (no Content-Length), the upstream server receives incomplete data which may cause application errors

See Also

TLS Interception

httpjail intercepts HTTPS traffic using a locally-generated Certificate Authority (CA) to inspect and filter encrypted requests.

How It Works

  1. CA Generation: On first run, httpjail creates a unique CA keypair
  2. Certificate Storage: CA files are stored in your config directory:
    • Linux: ~/.config/httpjail/
    • macOS: ~/Library/Application Support/httpjail/
    • Windows: %APPDATA%\httpjail\ (planned)
  3. Process Trust: The jailed process trusts the CA via environment variables
  4. Per-Host Certificates: Each HTTPS connection gets a certificate signed by the httpjail CA
  5. No System Changes: Your system trust store is never modified

Certificate Trust

httpjail sets these environment variables for the child process:

  • SSL_CERT_FILE / SSL_CERT_DIR - OpenSSL and most tools
  • CURL_CA_BUNDLE - curl
  • REQUESTS_CA_BUNDLE - Python requests
  • NODE_EXTRA_CA_CERTS - Node.js
  • CARGO_HTTP_CAINFO - Cargo
  • GIT_SSL_CAINFO - Git

Platform Differences

Linux (Strong Mode)

  • Transparently redirects TCP port 443 to the proxy
  • Extracts SNI from TLS ClientHello
  • No application cooperation needed

macOS (Weak Mode)

  • Uses HTTP_PROXY/HTTPS_PROXY environment variables
  • HTTPS negotiated via CONNECT method
  • Applications must respect proxy settings

Application Support

PlatformEnvironment VariablesSystem Trust Store
Linux๐ŸŸข Vast majorityN/A
macOS๐ŸŸ  Some๐ŸŸข Vast majority

Most CLI tools and libraries respect the CA environment variables that httpjail sets. On macOS, some tools (e.g. those built with Go) ignore these variables and require system trust. As Linux doesn't have a concept of a "system trust store" the environment variables are well supported.

On macOS, you can install the CA certificate to the keychain using httpjail trust --install.

DNS Exfiltration

httpjail prevents DNS exfiltration attacks by intercepting all DNS queries in isolated environments.

The Attack

Malicious code can exfiltrate sensitive data by encoding it in DNS queries:

  • secret-data.attacker.com
  • env-var-contents.evil.com
  • api-key-12345.tunnel.io

These queries reach public DNS servers even when HTTP/HTTPS traffic is blocked.

How Protection Works

In Linux strong mode, httpjail:

  1. Intercepts all DNS queries from the jailed process
  2. Returns dummy response (6.6.6.6) for every query
  3. Prevents external DNS access - queries never reach public resolvers
  4. Maintains HTTP/HTTPS functionality through transparent proxy redirection

Traffic Flow

sequenceDiagram
    participant J as Jailed Process
    participant S as Jail Server
    participant D as Public DNS Resolvers

    Note over J,D: DNS Exfiltration Attempt
    J->>S: DNS Query: secret-data.attacker.com
    S-->>J: Response: 6.6.6.6 (dummy)
    Note over S,D: โŒ Query never reaches public resolvers

    Note over J,D: Blocked HTTP Flow
    J->>S: HTTP GET http://blocked.com
    Note over S: Rule evaluation: denied
    S-->>J: 403 Forbidden
    Note over S,D: โŒ No DNS resolution needed

    Note over J,D: Allowed HTTP Flow
    J->>S: HTTP GET http://example.com
    Note over S: Rule evaluation: allowed
    S->>D: DNS Query: example.com (only if needed)
    D-->>S: Real IP address
    S->>S: Forward to upstream server
    S-->>J: HTTP response

The diagram shows three scenarios:

  1. DNS Exfiltration Prevention: All DNS queries receive dummy response, never reaching public resolvers
  2. Blocked HTTP Traffic: Requests denied by rules without any DNS resolution
  3. Allowed HTTP Traffic: Only when rules permit, httpjail performs actual DNS resolution

Platform Support

  • Linux (Strong Mode): Full DNS interception and protection
  • macOS (Weak Mode): No DNS interception - applications resolve normally
  • Windows: Planned

Why 6.6.6.6?

The choice of 6.6.6.6 is arbitrary - any non-lookback IP would work.

Server Mode

Run httpjail as a standalone proxy server without executing any commands. Useful for proxying multiple applications through the same httpjail instance.

The server binds to localhost (127.0.0.1) by default for security.

# Start server with default ports (8080 for HTTP, 8443 for HTTPS) on localhost
httpjail --server --js "true"

# Start server with custom ports using environment variables
HTTPJAIL_HTTP_BIND=3128 HTTPJAIL_HTTPS_BIND=3129 httpjail --server --js "true"

# Bind to all interfaces (use with caution - exposes proxy to network)
HTTPJAIL_HTTP_BIND=0.0.0.0:8080 HTTPJAIL_HTTPS_BIND=0.0.0.0:8443 httpjail --server --js "true"

# Configure your applications to use the proxy:
export HTTP_PROXY=http://localhost:8080
export HTTPS_PROXY=http://localhost:8443
curl https://github.com  # This request will go through httpjail

Note: In server mode, httpjail does not create network isolation. Applications must be configured to use the proxy via environment variables or application-specific proxy settings.

Server Mode is particularly powerful when paired with network-level firewall rules that force HTTP(s) traffic through the proxy.

Security Policy

Where to Report

Most security issues should be reported directly on our issue tracker. Given the early stage of this tool, we encourage clear and public disclosure to help the community stay informed and protected.

Particularly sensitive issues (e.g. those that could lead to arbitrary code execution on the host) should be reported privately to: security@coder.com

Disclosure Preference

Due to the tool's current maturity level, we prefer:

  • Early disclosure - Report issues as soon as they're discovered
  • Clear communication - Provide detailed reproduction steps and impact assessment
  • Public transparency - Use the issue tracker for most reports

As the project matures, we will implement more formal security disclosure processes, including coordinated disclosure timelines and security advisories.

Creative Commons Legal Code

CC0 1.0 Universal

CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.

Statement of Purpose

The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").

Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.

For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.

  1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:

i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.

  1. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.

  2. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.

  3. Limitations and Disclaimers.

a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.