# Dalfox Server Mode has an Unauthenticated Arbitrary File Create/Append via `output` Option

Unauthenticated dalfox REST server mode accepts attacker-controlled `output` path, letting any network caller create or append to arbitrary files writable by the process.

- Payout: Research
- Severity: high
- Program: Dalfox
- Found by: drmingler
- Disclosed: 2026-05-12
- CVE: CVE-2026-45089
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-8hf9-3q64-q2qf
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-8hf9-3q64-q2qf
- Tags: area:web domain:api domain:web impact:integrity kind:research platform:ghsa sev:high tech:go technique:source-review vuln:misconfiguration vuln:path-traversal

**Target:** Dalfox REST API server (/scan endpoint, model.Options deserialization)
**Root cause:** The `output`/`output-all`/`debug` fields of model.Options are bound directly from the request body and propagated into DalLog, whose os.OpenFile(O_APPEND|O_CREATE|O_WRONLY) block sits outside the IsLibrary guard, so it runs in server mode where file output was never intended.
**Steps:**
1. Start server: `go run . server --host 127.0.0.1 --port 16664 --type rest` (no --api-key by default).
2. POST to `/scan` with body `{"url":"http://127.0.0.1:1/?x=1","options":{"output":"/tmp/dalfox_sink_poc.log","output-all":true,"debug":true,"use-headless":false}}` — no X-API-KEY header.
3. Wait ~2s; the dalfox process creates/appends the file at the attacker-chosen path with scan log lines.
4. Point `output` at any writable path (e.g. `/etc/cron.d/dalfox`, web root) to create or corrupt files.
**How found:** Code review of the server handler and logger: noticed model.Options JSON tags expose filesystem fields, traced them through Initialize into DalLog, and spotted the os.OpenFile block positioned after and outside the IsLibrary if-else — meaning the CLI-only file write executes in library/server mode.
**Exploitation:** Unauthenticated network caller hits the default-bound 0.0.0.0:6664 REST endpoint, supplies an arbitrary filesystem path in `output` plus `output-all`/`debug` to populate ftext, and the process opens that path with O_CREATE|O_APPEND and writes semi-fixed log lines (including the attacker-supplied URL verbatim). No data is returned; the primitive is write-only file create/append within the dalfox process's OS authority.
**Escalation:** Blast radius grows when dalfox runs privileged (root in container, CI pipeline): can target cron drop-ins, web roots, config files; partial content control via the URL field may enable format injection.
**Insight:** When a tool has both CLI and embedded/library modes, audit every side-effecting block for mode guards: a guard on the primary output path (stderr vs ScanResult.Logs) does not cover secondary sinks like file writes placed after the if-else. Also check whether auth middleware is conditionally registered on a non-empty key default.

## Proof of concept (copied exactly from the original report)

**curl POST to /scan with attacker output path**

```
curl -s -X POST http://127.0.0.1:16664/scan \
  -H 'Content-Type: application/json' \
  --data '{
    "url": "http://127.0.0.1:1/?x=1",
    "options": {
      "output": "/tmp/dalfox_sink_poc.log",
      "output-all": true,
      "debug": true,
      "use-headless": false
    }
  }'

# Step 4 — Verify file was created and written to by the dalfox process
sleep 2
cat /tmp/dalfox_sink_poc.log
```

