openvibers/openvibe.trade Commits

Trade: nginx hardening from the pre-launch security review (#24)

OP OpenVibers committed 9 Oct 2026 · d86530a2a4 · 1 file, +13 −5

- Pages get a per-address limit (10 a second); the sitemaps, feeds and llms-full.txt, which read every public row,
  30 a minute. Only some write paths were limited before.
- /metrics and /internal/ are refused case-insensitively and with any suffix (Express routes /METRICS and /metrics/ too).
- location / no longer sets proxy headers of its own, which dropped the server's Host and X-Forwarded-Proto.

Changes

ddiff --git a/deploy/nginx/openvibe.trade.conf b/deploy/nginx/openvibe.trade.conf
iindex 43aa6ae..cf15707 100644
---- a/deploy/nginx/openvibe.trade.conf
++++ b/deploy/nginx/openvibe.trade.conf
@@@ -18,6 +18,9 @@
limit_req_zone $binary_remote_addr zone=ovtrade_api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=ovtrade_auth:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=ovtrade_write:10m rate=5r/s;
++# Pages per address; the sitemaps, feeds and llms-full.txt (each reads every public row) slower.
++limit_req_zone $binary_remote_addr zone=ovtrade_pages:10m rate=10r/s;
++limit_req_zone $binary_remote_addr zone=ovtrade_index:10m rate=30r/m;
server {
listen 80;
@@@ -89,7 +92,7 @@ server {
}
# ── Signed Events webhook: host-local only ──────────────
-- location /internal/ { return 404; }
++ location ~* ^/internal(/|$) { return 404; }
# ── API ─────────────────────────────────────────────────
location /api/ {
@@@ -98,14 +101,19 @@ server {
}
# ── Prometheus metrics: host-local scrapers only (http://127.0.0.1:4860/metrics) ──
-- location = /metrics { return 404; }
++ location ~* ^/metrics(/|$) { return 404; }
++
++ # ── Sitemaps, feeds and llms-full.txt: built from every public row on each request ──
++ location ~* ^/(sitemap[^/]*\.xml|sitemaps/|llms-full\.txt|feed\.|atom\.xml|.*/feed\.xml$) {
++ limit_req zone=ovtrade_index burst=10 nodelay;
++ proxy_pass http://127.0.0.1:4860;
++ }
# ── Pages, JSON twins, feeds, sitemaps, robots.txt, llms.txt, static assets ──
++ # (No proxy_set_header here: one would drop every server-level header, Host and X-Forwarded-Proto included.)
location / {
++ limit_req zone=ovtrade_pages burst=40 nodelay;
proxy_pass http://127.0.0.1:4860;
-- proxy_set_header X-Real-IP $remote_addr;
-- proxy_set_header X-Forwarded-For $remote_addr;
-- proxy_set_header CF-Connecting-IP $remote_addr;
}
location ~ /\.(?!well-known) {