---
title: "Security"
description: "curl-runner ships with secure defaults that limit what a request can reach and reveal, with explicit opt-outs when you need them."
category: "Documentation"
keywords:
  - curl-runner
  - http
  - api
  - testing
  - security
  - yaml
  - variables
  - headers
  - response
  - request
  - cli
  - environment
slug: "/docs/security"
toc: true
date: "2026-06-10T19:35:03.546Z"
lastModified: "2026-06-10T19:35:03.546Z"
author: "alexvcasillas"
authorUrl: "https://github.com/alexvcasillas/curl-runner"
license: "MIT"
nav:
  label: "Security"
  category: "Documentation"
tags:
  - documentation
  - documentation
og:
  title: "Security - curl-runner Documentation"
  description: "curl-runner ships with secure defaults that limit what a request can reach and reveal, with explicit opt-outs when you need them."
  type: "article"
  image: "/og-image.png"
schema:
  "@context": "https://schema.org"
  "@type": "TechArticle"
  headline: "Security"
  description: "curl-runner ships with secure defaults that limit what a request can reach and reveal, with explicit opt-outs when you need them."
  datePublished: "2026-06-10T19:35:03.546Z"
  dateModified: "2026-06-10T19:35:03.546Z"
---

# 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.

## 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**

```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**

```bash
# 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**

```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**

```bash
# 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**

```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
