# Verification Report: CivetWeb PUT + SSI #exec Authenticated RCE Fix

## Fix Summary

The vulnerability exists because CivetWeb's Server-Side Include (SSI) engine implements the `<!--#exec "command"-->` directive by passing the attacker-supplied command string directly to `popen()`. When combined with authenticated HTTP PUT uploads enabled by `put_delete_auth_file`, an authenticated user can upload a `.shtml` file containing an `#exec` tag and execute arbitrary shell commands by requesting that file. The fix removes the SSI `#exec` directive entirely from `src/civetweb.c`: the `do_ssi_exec()` function and the corresponding `exec` branch in `send_ssi_file()` are deleted. SSI `#include` and other SSI functionality remain intact, but no SSI tag can invoke `popen()`.

## Changes Made

- `src/civetweb.c`
  - Removed the `do_ssi_exec()` function, which parsed the SSI `#exec` tag and called `popen()` on the embedded command.
  - Removed the `exec` branch in `send_ssi_file()` that dispatched `<!--#exec ...-->` tags to `do_ssi_exec()`.
  - Removed the now-unused `#if !defined(NO_POPEN)` guards around the deleted code.

These changes are minimal and targeted: they eliminate the only SSI command-execution sink while preserving the rest of the SSI parser and `#include` behavior.

## Verification Steps

1. Exported the vulnerable source tree at commit `3309a6ca` (the last working revision before the ticket's target commit, which has an unrelated syntax error).
2. Applied `bundle/coding/proposed_fix.diff` to the exported tree with `patch -p1`.
3. Built the patched binary with `make -j$(nproc)`.
4. Started CivetWeb with the same configuration used in the reproduction stage: `listening_ports 8099`, `document_root`, `put_delete_auth_file`, and `authentication_domain`.
5. Created a digest password file for `admin:password`.
6. Performed an authenticated HTTP PUT of `/pwn.shtml` containing `<!--#exec "id; uname -a" -->`.
7. Performed an authenticated HTTP GET of `/pwn.shtml`.
8. Inspected the GET response body to confirm that it does NOT contain `uid=` or `Linux`, which would indicate command execution.

Commands run and results:

```bash
bash bundle/coding/verify_fix.sh
```

Output excerpts:

```
[VERIFY] ... Applying patch...
patching file src/civetweb.c
[VERIFY] ... Patch applied cleanly.
[VERIFY] ... Building patched binary...
... (make output) ...
[VERIFY] ... Patched binary built: .../verify-build-coding/civetweb
[VERIFY] ... PUT status: 200
[VERIFY] ... GET status: 200
[VERIFY] ... GET body:
[VERIFY] ... PASS: patched server accepted the PUT upload but did not execute the SSI #exec command.
```

The PUT returned `200`, confirming the uploaded file was stored. The GET also returned `200`, confirming the file was served. The GET body was empty, confirming the `#exec` directive was not executed.

## Test Results

- Patch applied cleanly without fuzz or rejects.
- Patched binary compiled successfully with default flags.
- Server started and responded to health checks.
- Authenticated PUT upload of `.shtml` succeeded.
- Authenticated GET of the uploaded `.shtml` returned HTTP 200 with an empty body.
- No `uid=` or `Linux` output appeared in the response body, confirming the command was not executed.
- The fix covers all attack paths that reach the SSI engine (direct PUT, chunked PUT, WebDAV MOVE to `.shtml`/`.shtm`, and `.shtm` extension) because the command-execution sink is removed entirely rather than restricting a specific upload path.

## Remaining Concerns

- The fix removes the `#exec` feature outright. Any legitimate users relying on SSI `#exec` for server-side scripting will need to migrate to a safer mechanism (e.g., CGI under strict controls, or application-level templates). This is an intentional security trade-off for a feature that allowed arbitrary command execution from files served by the web server.
- The broader trust boundary remains: authenticated users can still upload files that are later served by the same process. While this patch closes the `popen()` SSI sink, other script interpreters (CGI, Lua, etc.) should be reviewed and disabled if not required.
- A future hardening step would be to add a runtime configuration option to disable SSI processing entirely, or to restrict `ssi_pattern` to a safe subset of directives, but the immediate RCE is resolved by removing `#exec`.
- The `NO_POPEN` compile-time flag is no longer needed to block this sink; the vulnerable code is gone.
