openvibers/openvibe.run Commits

Run: nginx refuses /internal/ and /metrics case-insensitively (#12)

OP OpenVibers committed 10 Oct 2026 · ec8ddf83a4 · 1 file, +3 −3

* Run: nginx refuses /internal/ and /metrics case-insensitively

nginx config only. Express routes case-insensitively, so a case variant such as `/Internal/events` or `/METRICS` slipped past the case-sensitive `location /internal/ { return 404; }` and `location = /metrics { return 404; }` blocks and reached the app. Those paths were still guarded in the app (the Events signature, the loopback check on metrics). Both blocks are now `location ~* ^/internal(/|$)` and `location ~* ^/metrics(/|$)`. The independent security reviews of 2026-10-09/10 found this in several services; this applies it network-wide.

* Run: quote the job-stream regex location (nginx reads an unquoted {26} as a block)

Changes

ddiff --git a/deploy/nginx/openvibe.run.conf b/deploy/nginx/openvibe.run.conf
iindex 756ade2..558fa52 100644
---- a/deploy/nginx/openvibe.run.conf
++++ b/deploy/nginx/openvibe.run.conf
@@@ -87,7 +87,7 @@ server {
# ── The job stream: Server-Sent Events ──────────────────
# The ticket rides in ?ticket= (a browser cannot put a header on an EventSource), and a reconnect
# resumes with Last-Event-ID, which is forwarded verbatim.
-- location ~ ^/api/v1/jobs/job_[0-9A-HJKMNP-TV-Z]{26}/stream$ {
++ location ~ "^/api/v1/jobs/job_[0-9A-HJKMNP-TV-Z]{26}/stream$" {
limit_req zone=ovrun_stream burst=10 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:4920;
@@@ -109,10 +109,10 @@ server {
# ── Prometheus metrics: host-local scrapers only (http://127.0.0.1:4920/metrics) ──
# The app refuses a request that arrived through a proxy; the vhost refuses it at the edge too.
-- location = /metrics { return 404; }
++ location ~* ^/metrics(/|$) { return 404; }
# ── Host-local service endpoints (Events deliveries, other services on this host) ──
-- location /internal/ { return 404; }
++ location ~* ^/internal(/|$) { return 404; }
# ── The job API ─────────────────────────────────────────
location /api/ {