PST-072: /metrics is served to anyone when enabled without a token #801

Closed
opened 2026-10-10 10:56:42 +00:00 by tiagoagueda · 1 comment
Owner

Found in the security audit of 2026-10-10 (SECURITY-AUDIT-2026-10-10.md), run against main at c30851b from 8 to 10 October 2026, as PST-072. Severity: Informational.

The text below is the audit's entry, unchanged apart from links to the other issues it names. The finding was produced by automated review and checked by a second automated pass; re-check it before acting on it.


  • Severity: Informational
  • Category: information-disclosure
  • Location: src/postulo/core/views_metrics.py (24-30)
  • Found by: ownership review of core

Who can do it, and what they need. Any stranger, on an instance where the operator set POSTULO_METRICS_ENABLED=1 without a token.

How it works.

  1. GET /metrics.
  2. _authorised() returns True because token() is empty.
  3. metrics.render() exposes postulo_records{kind="people"} (account count), application/listing/company counts, pending captures and plugin counts.

Impact. Instance-level counts (how many people and records live here) are readable by anyone; no per-person data. Documented as deliberate on the Logs page, so informational.

Verification (verdict: confirmed; severity after verification: Informational). No correction to file, line or impact. Precondition is a double operator opt-in (POSTULO_METRICS_ENABLED on and no POSTULO_METRICS_TOKEN) made with the warning on the Logs page in view; the behaviour is pinned by tests/security/test_metrics.py and the output is verified to name nobody. Per-address throttling (throttle.endpoint) and no-store apply.

Suggested remediation. Require a token whenever the endpoint is enabled (refuse with 503 and a log line, as /logs does), or at least drop the account count from the open variant.

Found in the security audit of 2026-10-10 (`SECURITY-AUDIT-2026-10-10.md`), run against `main` at `c30851b` from 8 to 10 October 2026, as **PST-072**. Severity: **Informational**. The text below is the audit's entry, unchanged apart from links to the other issues it names. The finding was produced by automated review and checked by a second automated pass; re-check it before acting on it. --- - **Severity:** Informational - **Category:** information-disclosure - **Location:** `src/postulo/core/views_metrics.py` (24-30) - **Found by:** ownership review of core **Who can do it, and what they need.** Any stranger, on an instance where the operator set POSTULO_METRICS_ENABLED=1 without a token. **How it works.** 1. GET /metrics. 2. _authorised() returns True because token() is empty. 3. metrics.render() exposes postulo_records{kind="people"} (account count), application/listing/company counts, pending captures and plugin counts. **Impact.** Instance-level counts (how many people and records live here) are readable by anyone; no per-person data. Documented as deliberate on the Logs page, so informational. **Verification** (verdict: confirmed; severity after verification: Informational). No correction to file, line or impact. Precondition is a double operator opt-in (POSTULO_METRICS_ENABLED on and no POSTULO_METRICS_TOKEN) made with the warning on the Logs page in view; the behaviour is pinned by tests/security/test_metrics.py and the output is verified to name nobody. Per-address throttling (throttle.endpoint) and no-store apply. **Suggested remediation.** Require a token whenever the endpoint is enabled (refuse with 503 and a log line, as /logs does), or at least drop the account count from the open variant.
tiagoagueda added this to the 1.0.0 milestone 2026-10-10 10:58:07 +00:00
Author
Owner

Fixed in 16a2eae5b on main.

Fixed in 16a2eae5b on main.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#801
No description provided.