# Ziti Admin Console (ZAC) Node server: unauthenticated /api/schema endpoint allows arbitrary file read and SSRF

**URL:** <https://openziti.discourse.group/t/ziti-admin-console-zac-node-server-unauthenticated-api-schema-endpoint-allows-arbitrary-file-read-and-ssrf/6144>\
**Category:** Security Adivsories\
**Created:** [September 29, 2026, 7:47pm UTC](https://openziti.discourse.group/t/ziti-admin-console-zac-node-server-unauthenticated-api-schema-endpoint-allows-arbitrary-file-read-and-ssrf/6144 "2026-09-29T19:47:33Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![rgalletto](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/rgalletto/32/1508_2.png) [@rgalletto](https://openziti.discourse.group/u/rgalletto)\
**Post date:** [September 29, 2026, 7:47pm UTC](https://openziti.discourse.group/t/ziti-admin-console-zac-node-server-unauthenticated-api-schema-endpoint-allows-arbitrary-file-read-and-ssrf/6144/1 "2026-09-29T19:47:33Z")

</div>

## Summary

The ZAC Node backend exposes an unauthenticated `POST /api/schema` endpoint that dereferences a caller-supplied JSON schema with external reference resolution enabled. This lets an unauthenticated attacker make the server read local files (returned in the response) or issue server-side requests to arbitrary URLs (SSRF).

## Affected Component

- **Package:** `openziti/ziti-console` (Ziti Admin Console) — Node backend
- **File:** `server.js` — the `/api/schema` handler
- **Sink:** `@apidevtools/json-schema-ref-parser` `dereference()` run on the request body with file and http `$ref` resolvers enabled

## Vulnerability Class

- **Primary:** CWE-306 — Missing Authentication for Critical Function
- **Secondary:** CWE-22 — Improper Limitation of a Pathname (arbitrary file read); CWE-918 — Server-Side Request Forgery

## Attacker Model

An unauthenticated remote attacker with network access to the ZAC Node server. No credentials and no user interaction are required.

## Preconditions

ZAC running via the Node backend (`server.js`) in `node-api` or `classic` mode — the default container entrypoint. Deployments that serve only the static Angular application are **not** affected.

## Root Cause

`/api/schema` passes the request body straight into `json-schema-ref-parser`'s `dereference()` with its default resolvers enabled. A `$ref` pointing at a local file path makes the server read that file and return its contents; a `$ref` pointing at an `http`/`https` URL makes the server fetch it.

## Impact

Unauthenticated read of JSON/YAML-parseable files the ZAC process can access, including the runtime `settings.json` (SMTP credentials) and session files (controller session tokens), and SSRF from the ZAC host into reachable internal services.

- **CVSS v3.1:** 8.6 (High)
- **Vector:** `AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N`

**Not impacted:** static-only (SPA) deployments that never run `server.js`; no remote code execution.

## Package

`openziti/ziti-console` (app-ziti-console, Node backend / `node-api` mode)

## Affected Versions

- app-ziti-console `< 4.5.3`

## Patched Versions

- app-ziti-console `4.5.3`

## Remediation

Upgrade to 4.5.3, which removes the unused `/api/schema` handler and its `json-schema-ref-parser` import (the console resolves schema references in the browser, so the endpoint was dead code). If you cannot upgrade, block `POST /api/schema` at a reverse proxy, or run ZAC in static-asset (SPA) mode instead of the Node proxy.

## References

- GHSA: [https://github.com/openziti/ziti-console/security/advisories/GHSA-37wj-4gv3-98rj](https://github.com/openziti/ziti-console/security/advisories/GHSA-37wj-4gv3-98rj)
- CVE: (pending)

## Credits

Reported by dmuensterer and sajdakabir.
