## Summary

A materially distinct alternate trigger was confirmed on the vulnerable Feast revision: the Feast **Web UI** server also exposed unauthenticated `POST /save-document` and used the same arbitrary JSON file-write sink as the Feature Server endpoint from the parent reproduction. This Web UI entrypoint can write attacker-controlled JSON into a feature repository, after which the real Feast Feature Server startup path (`load_static_artifacts()`) can consume that file and execute the configured startup hook in the demonstrated deployment chain. This is **not a bypass** of the tested fix, because commit `4018e7b0c39825a5647fb17fc5607d72fb4bc0ce` removes both the Feature Server document endpoints and the Web UI `/save-document` endpoint; the fixed UI runtime returned HTTP `405` and did not create any attacker-controlled file.

## Fix Coverage / Assumptions

The original fix relies on a broad invariant: no remotely reachable document read/write endpoint should remain in Feast's Python servers. Instead of attempting to repair path validation, commit `4018e7b0c39825a5647fb17fc5607d72fb4bc0ce` deletes the affected endpoint definitions and request models.

Explicitly covered code paths:

- `sdk/python/feast/feature_server.py`
  - removes `ReadDocumentRequest`
  - removes `SaveDocumentRequest`
  - removes `@app.post("/read-document", dependencies=[Depends(inject_user_details)])`
  - removes `@app.post("/save-document", dependencies=[Depends(inject_user_details)])`
- `sdk/python/feast/ui_server.py`
  - removes `SaveDocumentRequest`
  - removes unauthenticated `@app.post("/save-document")`
- `sdk/python/tests/unit/test_ui_server.py`
  - removes tests that exercised the now-deleted document endpoints.

The fix does not remove `feature_server.py::load_static_artifacts()`. That function remains an intentional Feast startup extension point that imports `static_artifacts.py` from the active feature repository. It is not itself the same remote file-write bug; it becomes part of the exploit chain only when an attacker can remotely write deployment data/configuration into a location consumed by that extension.

A top-level `SECURITY.md` was not present in the tested repository. Relevant in-repo threat-model/security documentation was the Feast permissions documentation, which states that authorization enforcement applies on Feast Python servers and that the default configuration is `no_auth`, meaning no permission enforcement is applied. The Web UI `/save-document` endpoint had no auth dependency at all, and the parent Feature Server endpoint was reachable in a `no_auth` deployment.

## Variant / Alternate Trigger

Confirmed alternate trigger:

- Entry point: Feast Web UI `POST /save-document`
- Component: `sdk/python/feast/ui_server.py`
- Vulnerable code path on commit `be1b52227e1ade9a3be9836391ade45eb1a26909`:
  - `ui_server.get_app(...)`
  - `@app.post("/save-document")`
  - `save_document_endpoint(request: SaveDocumentRequest)`
  - `Path(request.file_path).resolve()`
  - naive `str(file_path).startswith(os.getcwd())`
  - derived `labels_file = file_path.parent / f"{base_name}-labels.json"`
  - `json.dump(request.data, file, ...)`

The variant proof starts the vulnerable Web UI server with `cwd=/`, sends an unauthenticated JSON POST with `file_path` pointing at `ui_variant_static_artifacts.json` in the active feature repository, and confirms the endpoint writes `ui_variant_static_artifacts-labels.json`. The script then starts the real Feast Feature Server against that same repository. Its `load_static_artifacts()` startup hook imports `static_artifacts.py`, which consumes the UI-written JSON and executes the configured startup hook, creating a marker file.

Negative fixed-version test:

- Entry point tested: same Web UI `POST /save-document`
- Fixed target: commit `4018e7b0c39825a5647fb17fc5607d72fb4bc0ce`
- Observed behavior: `HAS_SAVE_DOCUMENT=False`, HTTP `405`, no dropped config, no marker.

Latest/default-branch check:

- `origin/master` resolved to `f296d4ba14c5d512429219b2b7845673e0fe524d` during this run.
- Static scan found no `save-document` or `read-document` in the relevant server files.

## Impact

- Package/component affected: Feast (`feast-dev/feast`), Python Web UI server and Python Feature Server startup/static-artifact integration.
- Affected versions as tested: vulnerable at commit `be1b52227e1ade9a3be9836391ade45eb1a26909`; fixed at commit `4018e7b0c39825a5647fb17fc5607d72fb4bc0ce`; latest observed `origin/master` `f296d4ba14c5d512429219b2b7845673e0fe524d` did not contain the endpoints.
- Risk level and consequences: Critical on vulnerable revisions exposing the Web UI server to untrusted clients. An unauthenticated attacker can place arbitrary JSON files in locations writable by the Feast process when the path-prefix check is bypassed. In deployments where startup/static-artifact components consume such files, this can lead to code execution as the Feast service account.

## Impact Parity

- Disclosed/claimed maximum impact for the parent: unauthenticated arbitrary file write leading to remote code execution.
- Reproduced impact from this variant run: code execution through an alternate Web UI entrypoint on the vulnerable commit. The proof creates `bundle/vuln_variant/artifacts/ui_variant_rce_marker.vulnerable.txt` containing `FEAST_UI_SAVE_DOCUMENT_VARIANT_RCE`, `written_by=Feast Web UI /save-document`, and `executed_by=Feast feature_server load_static_artifacts`.
- Parity: `full` for the vulnerable-version alternate trigger; `none` as a patched-version bypass because the fixed target blocks/removes the entrypoint.
- Not demonstrated: privilege escalation beyond the Feast service account was not attempted. The fixed/latest versions were not vulnerable in the tested path.

## Root Cause

The same underlying bug existed in two HTTP servers: both the Feature Server and the Web UI server exposed document-write endpoints that trusted a user-supplied `file_path` and attempted to constrain it with string-prefix validation against `os.getcwd()`. This validation is not a directory containment check. When the process working directory is `/`, every absolute path begins with `/`; when the working directory is a path prefix of a sibling directory, a resolved sibling path can still pass `startswith()`.

The vulnerable Web UI sink in `sdk/python/feast/ui_server.py` is equivalent to the parent Feature Server sink:

```python
file_path = Path(request.file_path).resolve()
if not str(file_path).startswith(os.getcwd()):
    return {"error": "Invalid file path"}

base_name = file_path.stem
labels_file = file_path.parent / f"{base_name}-labels.json"
with open(labels_file, "w", encoding="utf-8") as file:
    json.dump(request.data, file, indent=2, ensure_ascii=False)
```

The fix commit is `4018e7b0c39825a5647fb17fc5607d72fb4bc0ce` (`Clean up document endpoints`). It removes both known document-write entrypoints, including the UI variant path, so the variant does not survive the patch.

## Reproduction Steps

1. Run `bundle/vuln_variant/reproduction_steps.sh`.
2. The script creates isolated worktrees under `bundle/vuln_variant/worktrees/` for:
   - vulnerable commit `be1b52227e1ade9a3be9836391ade45eb1a26909`, and
   - fixed commit `4018e7b0c39825a5647fb17fc5607d72fb4bc0ce`.
3. It records `origin/master` as the latest/default-branch check in `bundle/logs/vuln_variant/latest_version.txt`.
4. It starts the vulnerable Feast Web UI server, sends an unauthenticated POST to `/save-document`, and confirms that `ui_variant_static_artifacts-labels.json` is written.
5. It starts the real vulnerable Feast Feature Server with the same feature repository and confirms `load_static_artifacts()` consumes the UI-written JSON and executes the configured startup hook.
6. It starts the fixed Feast Web UI server and sends the same request. The fixed server reports no registered `/save-document`, returns HTTP `405`, and creates neither the config file nor the marker.

Expected script result is exit code `1`, because the variant is confirmed only on the vulnerable version and is not a patched-version bypass. The script still completes fully and idempotently.

## Evidence

Primary evidence files:

- `bundle/logs/vuln_variant/reproduction_steps.log` — full transcript of the second verified run.
- `bundle/logs/vuln_variant/vuln_ui_writer.log` — vulnerable Web UI startup log; includes `HAS_SAVE_DOCUMENT=True` and the request handling.
- `bundle/vuln_variant/artifacts/http/vuln_ui_save_request.json` — attacker-controlled unauthenticated POST body.
- `bundle/vuln_variant/artifacts/http/vuln_ui_save_response.json` — vulnerable response showing `success: true` and `saved_to` ending in `ui_variant_static_artifacts-labels.json`.
- `bundle/vuln_variant/artifacts/feature_repo_ui/ui_variant_static_artifacts-labels.json.vuln` — exact JSON file written by the vulnerable UI endpoint.
- `bundle/logs/vuln_variant/vuln_feature_consumer.log` — Feature Server startup log proving the product path consumed the UI-written config and executed the startup hook.
- `bundle/vuln_variant/artifacts/ui_variant_rce_marker.vulnerable.txt` — code-execution marker created by the startup hook.
- `bundle/logs/vuln_variant/fixed_ui_writer.log` — fixed Web UI startup log; includes `HAS_SAVE_DOCUMENT=False`.
- `bundle/vuln_variant/artifacts/http/fixed_ui_save_status.txt` — fixed request status (`405`).
- `bundle/logs/vuln_variant/fixed_version.txt` and `bundle/logs/vuln_variant/latest_version.txt` — source identity for fixed/latest checks.
- `bundle/vuln_variant/runtime_manifest.json` — structured runtime manifest for the variant run.

Key observed transcript excerpts from `reproduction_steps.log`:

```text
[EXPLOIT] Sending unauthenticated POST to vulnerable Feast Web UI /save-document
{"success":true,"saved_to":".../ui_variant_static_artifacts-labels.json"}
[RCE] UI variant marker:
FEAST_UI_SAVE_DOCUMENT_VARIANT_RCE
written_by=Feast Web UI /save-document
executed_by=Feast feature_server load_static_artifacts
[FIXED] /save-document status on patched UI server: 405
Patch bypass: no.
```

## Recommendations / Next Steps

The tested fix appears complete for this bug class because it removes both known document-write entrypoints. Recommended follow-up:

- Keep `/save-document` and `/read-document` absent from all remotely reachable Feast servers unless there is a strong product requirement.
- Add regression tests asserting that both `feature_server.get_app()` and `ui_server.get_app()` do not register `/save-document` or `/read-document`.
- Add a static regression check for remote handlers that combine `Path.resolve()`, `str(...).startswith(os.getcwd())`, and filesystem writes.
- If file/document endpoints are ever reintroduced, enforce authentication/authorization and use real containment checks such as `resolved_path.is_relative_to(allowed_base.resolve())` or equivalent parent-path comparisons.
- Avoid deriving output paths from attacker-controlled absolute paths; use server-controlled storage roots and server-generated filenames.

## Additional Notes

- Idempotency: `bundle/vuln_variant/reproduction_steps.sh` was run twice consecutively. Both runs completed successfully and exited `1` as expected for a non-bypass alternate trigger.
- The script uses isolated worktrees under `bundle/vuln_variant/worktrees/` and does not mutate the reproduction checkout.
- Source identities are recorded in `bundle/vuln_variant/source_identity.json`, `bundle/vuln_variant/variant_manifest.json`, and logs under `bundle/logs/vuln_variant/`.
- The RCE chain uses a realistic Feast extension point (`load_static_artifacts()`), but depends on a deployment component that consumes JSON from the feature repository. Environments without such a consumer still have the arbitrary JSON write primitive on the vulnerable Web UI endpoint, but may require a different local chain for code execution.
