Skip to content

feat(demo): add docker/demo compose with NEXTAUTH_URL for demo.vectorflow.sh#190

Closed
TerrifiedBug wants to merge 2 commits intomainfrom
wuphf-b307de83-task-6
Closed

feat(demo): add docker/demo compose with NEXTAUTH_URL for demo.vectorflow.sh#190
TerrifiedBug wants to merge 2 commits intomainfrom
wuphf-b307de83-task-6

Conversation

@TerrifiedBug
Copy link
Copy Markdown
Owner

Summary

  • Adds docker/demo/docker-compose.yml — dedicated compose for the hosted demo deployment at demo.vectorflow.sh
  • Pins NEXTAUTH_URL=https://demo.vectorflow.sh so auth callback URLs resolve correctly
  • Sets VF_DEMO_MODE=true to ensure demo guards are active (guards egress/identity mutations)
  • AUTH_TRUST_HOST=true is already set (PR feat(demo): harden hosted demo against egress + identity mutations #184); this compose hardcodes the canonical URL so NextAuth doesn't infer a wrong origin
  • Adds docker/demo/.env.example for required secrets (POSTGRES_PASSWORD, NEXTAUTH_SECRET)
  • Clarifies comment in docker/server/.env.example to point operators to the new demo compose

Test plan

  • Deploy docker/demo/docker-compose.yml to demo.vectorflow.sh with valid .env secrets
  • Verify login at https://demo.vectorflow.sh/login completes without UntrustedHost error
  • Verify auth callback URL in browser resolves to demo.vectorflow.sh not another origin

…low.sh

Single-instance docker-compose.yml was missing AUTH_TRUST_HOST=true, which
caused NextAuth UntrustedHost errors on demo.vectorflow.sh. Dev and HA composes
already had it. Also clarifies NEXTAUTH_URL guidance in .env.example with an
explicit demo example.
…ctorflow.sh

Adds a dedicated docker/demo/docker-compose.yml for the hosted demo
deployment at demo.vectorflow.sh. AUTH_TRUST_HOST is already true from
PR #184; this compose pins NEXTAUTH_URL so auth callback URLs resolve
to the correct origin and adds VF_DEMO_MODE=true so demo guards are active.

Also adds docker/demo/.env.example for required secrets and clarifies
the comment in docker/server/.env.example to point to the new compose.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 27, 2026

Greptile Summary

This PR adds a dedicated docker/demo/docker-compose.yml for the hosted demo deployment at demo.vectorflow.sh, pins NEXTAUTH_URL and VF_DEMO_MODE for that environment, and also adds AUTH_TRUST_HOST: "true" to the generic docker/server/docker-compose.yml.

  • The demo compose is correctly configured — NEXTAUTH_URL is hardcoded, so host-header inference never applies.
  • The server compose now ships AUTH_TRUST_HOST unconditionally while NEXTAUTH_URL remains optional; without a required default, operators who omit NEXTAUTH_URL are left with host-header-inferred origins that an attacker can spoof to redirect OAuth callbacks.

Confidence Score: 3/5

The demo compose is safe as-is; the server compose ships a security-relevant default that can leave self-hosted deployments open to host-header injection when operators omit NEXTAUTH_URL.

One P1 security finding in docker/server/docker-compose.yml — AUTH_TRUST_HOST is now on by default while NEXTAUTH_URL is still optional with no required guard. Score is below the P1 ceiling of 4 because this affects the general-purpose server compose used by all self-hosted operators, not just the demo path.

docker/server/docker-compose.yml — needs either AUTH_TRUST_HOST removed or NEXTAUTH_URL made required before merge.

Security Review

  • Host-header injection / open redirect (docker/server/docker-compose.yml): AUTH_TRUST_HOST is enabled unconditionally while NEXTAUTH_URL remains an optional env var with no required default. When NEXTAUTH_URL is unset, NextAuth v5 infers its canonical URL from X-Forwarded-Host; if port 3000 is reachable without a sanitizing proxy, an attacker can inject an arbitrary host and hijack OAuth/credentials callback destinations.

Important Files Changed

Filename Overview
docker/server/docker-compose.yml Adds AUTH_TRUST_HOST: true without requiring NEXTAUTH_URL, creating a host-header injection risk when the env var is unset.
docker/demo/docker-compose.yml New demo compose for demo.vectorflow.sh; pins the canonical URL and enables demo-mode guard, auth config is correct.
docker/demo/.env.example New env example listing required secrets with clear placeholder values.
docker/server/.env.example Improved comment for NEXTAUTH_URL clarifying when and why to set it, and pointing operators to the demo compose.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Operator runs docker compose up] --> B{NEXTAUTH_URL set?}
    B -- Yes --> C[NextAuth uses explicit canonical URL\nCallback URLs resolve correctly]
    B -- No / Empty --> D{AUTH_TRUST_HOST true?}
    D -- false --> E[NextAuth uses localhost fallback\nOAuth callbacks likely broken]
    D -- true --> F[NextAuth infers URL from\nX-Forwarded-Host header]
    F --> G{Request via trusted proxy?}
    G -- Yes, proxy controls headers --> H[Correct canonical URL inferred\nAuth works correctly]
    G -- No, port 3000 exposed directly --> I[Attacker injects X-Forwarded-Host: attacker.com\nNextAuth trusts attacker domain as valid origin]
    I --> J[Open redirect / OAuth callback hijack]

    style I fill:#f66,color:#fff
    style J fill:#f66,color:#fff
    style C fill:#6b6,color:#fff
    style H fill:#6b6,color:#fff
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: docker/server/docker-compose.yml
Line: 32

Comment:
**Host-header injection risk from `AUTH_TRUST_HOST` with optional `NEXTAUTH_URL`**

When `AUTH_TRUST_HOST` is `"true"` and `NEXTAUTH_URL` is absent or empty, NextAuth v5 infers its canonical URL from the `X-Forwarded-Host` / `Host` request header. In this compose, `NEXTAUTH_URL` comes from an optional env var with no required default, so Docker passes an empty string when operators omit it. An attacker who can reach port 3000 directly and inject a crafted `X-Forwarded-Host` header can make NextAuth treat their domain as a valid callback origin, enabling open-redirect and OAuth callback-hijacking.

The demo compose avoids this correctly by hardcoding the canonical URL. The server compose should either remove `AUTH_TRUST_HOST` (operators who need it can add it themselves when they also set `NEXTAUTH_URL`), or enforce that `NEXTAUTH_URL` is provided using Docker Compose's `${VAR:?error message}` required-variable syntax, which aborts startup with a clear error if the variable is unset.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(demo): add docker/demo compose with..." | Re-trigger Greptile

DATABASE_URL: postgresql://vectorflow:${POSTGRES_PASSWORD}@postgres:5432/vectorflow
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
NEXTAUTH_URL: ${NEXTAUTH_URL}
AUTH_TRUST_HOST: "true"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Host-header injection risk from AUTH_TRUST_HOST with optional NEXTAUTH_URL

When AUTH_TRUST_HOST is "true" and NEXTAUTH_URL is absent or empty, NextAuth v5 infers its canonical URL from the X-Forwarded-Host / Host request header. In this compose, NEXTAUTH_URL comes from an optional env var with no required default, so Docker passes an empty string when operators omit it. An attacker who can reach port 3000 directly and inject a crafted X-Forwarded-Host header can make NextAuth treat their domain as a valid callback origin, enabling open-redirect and OAuth callback-hijacking.

The demo compose avoids this correctly by hardcoding the canonical URL. The server compose should either remove AUTH_TRUST_HOST (operators who need it can add it themselves when they also set NEXTAUTH_URL), or enforce that NEXTAUTH_URL is provided using Docker Compose's ${VAR:?error message} required-variable syntax, which aborts startup with a clear error if the variable is unset.

Prompt To Fix With AI
This is a comment left during a code review.
Path: docker/server/docker-compose.yml
Line: 32

Comment:
**Host-header injection risk from `AUTH_TRUST_HOST` with optional `NEXTAUTH_URL`**

When `AUTH_TRUST_HOST` is `"true"` and `NEXTAUTH_URL` is absent or empty, NextAuth v5 infers its canonical URL from the `X-Forwarded-Host` / `Host` request header. In this compose, `NEXTAUTH_URL` comes from an optional env var with no required default, so Docker passes an empty string when operators omit it. An attacker who can reach port 3000 directly and inject a crafted `X-Forwarded-Host` header can make NextAuth treat their domain as a valid callback origin, enabling open-redirect and OAuth callback-hijacking.

The demo compose avoids this correctly by hardcoding the canonical URL. The server compose should either remove `AUTH_TRUST_HOST` (operators who need it can add it themselves when they also set `NEXTAUTH_URL`), or enforce that `NEXTAUTH_URL` is provided using Docker Compose's `${VAR:?error message}` required-variable syntax, which aborts startup with a clear error if the variable is unset.

How can I resolve this? If you propose a fix, please make it concise.

@TerrifiedBug
Copy link
Copy Markdown
Owner Author

Closing — wrong repo. Demo compose lives in vectorflow-demo-ops (private), not the main app repo. This was a tool test artifact.

@TerrifiedBug TerrifiedBug deleted the wuphf-b307de83-task-6 branch April 28, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant