feat(security): bind services to loopback with Host + CORS allowlists

The Synapse backend and memory service bound 0.0.0.0 with wildcard CORS and no
auth, exposing the full unauthenticated admin/data API to the LAN. Default the
uvicorn bind to 127.0.0.1 (NEXUS_BIND_HOST override), scope CORS to known local
origins instead of "*", and add TrustedHostMiddleware to reject foreign Host
headers (which defeats DNS-rebinding, something same-origin CORS cannot stop).

NEXUS_ALLOWED_HOSTS / NEXUS_ALLOWED_ORIGINS allow opt-in LAN exposure, intended
to be paired with real authentication.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-07 09:40:12 -05:00
co-authored by Cursor
parent e8379786d3
commit fe12eb1821
4 changed files with 54 additions and 9 deletions
+8 -1
View File
@@ -19,17 +19,24 @@ from typing import Any, Dict, List, Optional
from fastapi import FastAPI, HTTPException, Body
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.trustedhost import TrustedHostMiddleware
from pydantic import BaseModel
from .store import store, MemoryItem
from .extractor import extract_memory
from ..ollama_manager import get_ollama_manager
from ..nexus_config import ALLOWED_HOSTS, ALLOWED_ORIGINS
app = FastAPI(title="Nexus Memory Service", version="1.0")
# Same unauthenticated-local-only posture as the main backend: reject foreign
# Host headers (anti DNS-rebind) and scope CORS to known local origins rather
# than "*". See nexus_config.ALLOWED_HOSTS / ALLOWED_ORIGINS for env overrides.
if "*" not in ALLOWED_HOSTS:
app.add_middleware(TrustedHostMiddleware, allowed_hosts=ALLOWED_HOSTS)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_origins=ALLOWED_ORIGINS,
allow_credentials=False,
allow_methods=["*"],
allow_headers=["*"],