Security

curl-runner ships with secure defaults that limit what a request can reach and reveal, with explicit opt-outs when you need them.

Overview

Because curl-runner builds and runs curl commands from YAML — and can feed values from one response into later requests — untrusted configs or responses could otherwise reach internal services, read or overwrite local files, or leak credentials. The controls below are on by default and can be relaxed per run.

Protocol Allow-List

Only http/https run unless you opt in to more

Path Confinement

File reads/writes stay in the working directory

Secret Redaction

Credentials are masked in output and saved files

URL Protocol Allow-List

Requests may only use http and https by default. Any other scheme (file, ftp, gopher, …) is rejected before curl is invoked, and redirects are likewise prevented from crossing into a disallowed protocol. This guards against SSRF and local file disclosure — including via values interpolated from a previous response.

curl-runner.yaml
# Allow extra protocols for a whole run (config file)
global:
  security:
    # Default is [http, https]. Add others only if you need them.
    allowedProtocols: [http, https, ftp]
CLI & Environment
# Permit additional protocols on the command line (repeatable)
curl-runner tests/ --allow-protocol ftp --allow-protocol file

# Or via environment variable (comma-separated)
CURL_RUNNER_ALLOWED_PROTOCOLS=http,https,ftp curl-runner tests/

# Blocked by default — fails before curl runs:
#   url: file:///etc/passwd
#   url: gopher://127.0.0.1:6379/

Filesystem Path Confinement

The output path, the global saveToFile path, and formData file attachments must resolve inside the current working directory. Paths that escape via .. or an absolute location are blocked unless you opt out. SSL ca/cert/key paths are exempt: they are TLS handshake material and are never transmitted to the server.

upload.yaml
# By default these paths must stay inside the working directory
request:
  name: Upload report
  url: https://api.example.com/upload
  method: POST
  formData:
    file:
      file: ./report.pdf        # OK: inside the working directory
      # file: /etc/passwd       # Blocked unless --allow-path is set
  output: ./results/upload.json  # OK
  # output: ../outside.json      # Blocked unless --allow-path is set
CLI & Environment
# Allow paths outside the working directory (opt-out)
curl-runner upload.yaml --allow-path

# Or via environment variable
CURL_RUNNER_ALLOW_PATHS=true curl-runner upload.yaml

Secret Redaction

Credentials are automatically masked as [REDACTED] in console output and in saved result files. This covers auth.token and auth.password, header values whose name looks sensitive (authorization, api-key, token, secret, cookie), environment variables prefixed with SECRET_, and a set of well-known key formats (Stripe, AWS, GitHub, JWTs, and more). Redaction is best-effort, not a guarantee — treat it as a safety net, not a reason to commit secrets.

api.yaml
# Secrets in your config are masked in console output and saved files
request:
  name: Get profile
  url: https://api.example.com/me
  auth:
    type: bearer
    token: ${API_TOKEN}        # masked as [REDACTED] in output
  headers:
    X-Api-Key: ${SECRET_KEY}   # sensitive header names are masked too

# Disable redaction if you really need raw output
# curl-runner api.yaml --no-redact

Upgrading

Recommended

• Keep the defaults; opt in only for the run that needs it
• Prefer config-file scoping over global environment variables
• Store credentials in env vars, not inline in committed YAML

Behavior changes

• Non-http(s) URLs now need --allow-protocol
• Files outside the working dir need --allow-path
• Disable masking with --no-redact if it gets in the way