- Create server/src/utils/ssrfGuard.ts with checkSsrf() and createPinnedAgent()
- Resolves DNS before allowing outbound requests to catch hostnames that
map to private IPs (closes the TOCTOU gap in the old inline checks)
- Always blocks loopback (127.x, ::1) and link-local/metadata (169.254.x)
- RFC-1918, CGNAT (100.64/10), and IPv6 ULA ranges blocked by default;
opt-in via ALLOW_INTERNAL_NETWORK=true for self-hosters running Immich
on a local network
- createPinnedAgent() pins node-fetch to the validated IP, preventing
DNS rebinding between the check and the actual connection
- Replace isValidImmichUrl() (hostname-string check, no DNS resolution)
with checkSsrf(); make PUT /integrations/immich/settings async
- Audit log entry (immich.private_ip_configured) written when a user
saves an Immich URL that resolves to a private IP
- Response includes a warning field surfaced as a toast in the UI
- Replace ~20 lines of duplicated inline SSRF logic in the link-preview
handler with a single checkSsrf() call + pinned agent
- Document ALLOW_INTERNAL_NETWORK in README, docker-compose.yml,
server/.env.example, chart/values.yaml, chart/templates/configmap.yaml,
and chart/README.md
28 lines
1.9 KiB
Plaintext
28 lines
1.9 KiB
Plaintext
PORT=3001 # Port to run the server on
|
|
NODE_ENV=development # development = development mode; production = production mode
|
|
# ENCRYPTION_KEY=<random-256-bit-hex> # Separate key for encrypting stored secrets (API keys, MFA, SMTP, OIDC, etc.)
|
|
# Auto-generated and persisted to ./data/.encryption_key if not set.
|
|
# Upgrade from a version that used JWT_SECRET for encryption: set to your old JWT_SECRET value so
|
|
# existing encrypted data remains readable, then re-save credentials via the admin panel.
|
|
# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
|
TZ=UTC # Timezone for logs, reminders and scheduled tasks (e.g. Europe/Berlin)
|
|
LOG_LEVEL=info # info = concise user actions; debug = verbose admin-level details
|
|
|
|
ALLOWED_ORIGINS=https://trek.example.com # Comma-separated origins for CORS and email links
|
|
FORCE_HTTPS=false # Redirect HTTP → HTTPS behind a TLS proxy
|
|
TRUST_PROXY=1 # Number of trusted proxies for X-Forwarded-For
|
|
ALLOW_INTERNAL_NETWORK=false # Allow outbound requests to private/RFC1918 IPs (e.g. Immich hosted on your LAN). Loopback and link-local addresses are always blocked.
|
|
|
|
APP_URL=https://trek.example.com # Base URL of this instance — required when OIDC is enabled; must match the redirect URI registered with your IdP
|
|
|
|
OIDC_ISSUER=https://auth.example.com # OpenID Connect provider URL
|
|
OIDC_CLIENT_ID=trek # OpenID Connect client ID
|
|
OIDC_CLIENT_SECRET=supersecret # OpenID Connect client secret
|
|
OIDC_DISPLAY_NAME=SSO # Label shown on the SSO login button
|
|
OIDC_ONLY=true # Disable local password auth entirely (SSO only)
|
|
OIDC_ADMIN_CLAIM=groups # OIDC claim used to identify admin users
|
|
OIDC_ADMIN_VALUE=app-trek-admins # Value of the OIDC claim that grants admin role
|
|
OIDC_DISCOVERY_URL= # Override the auto-constructed discovery endpoint (e.g. Authentik: https://auth.example.com/application/o/trek/.well-known/openid-configuration)
|
|
|
|
DEMO_MODE=false # Demo mode - resets data hourly
|