Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Langgenius Dify Security Middleware

From Leeroopedia
Revision as of 11:28, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Langgenius_Dify_Security_Middleware.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Knowledge Sources
Domains Frontend, Security, Middleware
Last Updated 2026-02-12 07:00 GMT

Overview

Next.js middleware that enforces Content-Security-Policy headers with nonce-based script protection and X-Frame-Options for clickjacking prevention, while allowing iframe embedding for designated chatbot and workflow paths.

Description

The web/proxy.ts module implements a Next.js middleware function named proxy that intercepts all non-static requests to apply security headers. It addresses two primary web security concerns: cross-site scripting (XSS) mitigation through Content Security Policy (CSP) and clickjacking prevention through X-Frame-Options.

When CSP is enabled (determined by the presence of NEXT_PUBLIC_CSP_WHITELIST in production), the middleware generates a cryptographically random nonce using crypto.randomUUID() encoded in Base64. This nonce is embedded into a comprehensive CSP header that governs default-src, connect-src, script-src, style-src, worker-src, media-src, img-src, font-src, object-src, base-uri, and form-action directives. The CSP combines the nonce, user-configured whitelist domains, and a necessary domain list that includes Sentry, Google Analytics, Google Tag Manager, GitHub API, and Amplitude. The style-src directive includes 'unsafe-inline' to accommodate dynamically injected styles. The nonce is passed to downstream rendering via the x-nonce request header.

For clickjacking protection, the wrapResponseWithXFrameOptions helper sets X-Frame-Options: DENY on all responses except those for paths that are designed to be embedded in iframes: /chat, /workflow, /completion, and /webapp-signin. This behavior can be globally disabled with the NEXT_PUBLIC_ALLOW_EMBED environment variable.

The middleware matcher excludes static assets (_next/static, _next/image, favicon.ico) from processing.

Usage

This middleware is applied automatically by Next.js to all matching requests. No explicit invocation is needed. Configure the CSP whitelist via the NEXT_PUBLIC_CSP_WHITELIST environment variable in production to enable the full CSP header. The nonce value is accessible in server components via the x-nonce request header for embedding in script tags.

Code Reference

Source Location

Signature

import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'

const NECESSARY_DOMAIN: string

const wrapResponseWithXFrameOptions = (response: NextResponse, pathname: string): NextResponse

export function proxy(request: NextRequest): NextResponse

export const config: {
  matcher: [{ source: '/((?!_next/static|_next/image|favicon.ico).*)' }]
}

Import

// Imported by the Next.js middleware entry point (web/middleware.ts):
import { proxy } from '@/proxy'

// Used within the middleware function:
export function middleware(request: NextRequest) {
  return proxy(request)
}

I/O Contract

Inputs

Name Type Required Description
request NextRequest Yes The incoming HTTP request object provided by the Next.js middleware pipeline
request.nextUrl.pathname string Yes (implicit) The URL path used to determine X-Frame-Options and CSP application
env.NEXT_PUBLIC_CSP_WHITELIST string No Space-separated list of allowed domains for CSP directives; CSP is only active when this is set in production
env.NEXT_PUBLIC_ALLOW_EMBED boolean No When true, disables X-Frame-Options entirely, allowing all pages to be embedded
env.NODE_ENV string Yes Must be production for CSP to be active

Outputs

Name Type Description
NextResponse NextResponse Modified response with security headers applied
Content-Security-Policy header string CSP header with nonce, whitelist, and scheme sources (production only, when whitelist is configured)
X-Frame-Options header string Set to DENY for non-embeddable paths; omitted for chat/workflow/completion/webapp-signin paths
x-nonce request header string Base64-encoded nonce value forwarded to downstream server components for script tag injection

Usage Examples

CSP Header Output (Production with Whitelist)

Content-Security-Policy:
  default-src 'self' data: mediastream: blob: filesystem: 'nonce-YWJjZGVm...' example.com *.sentry.io ...;
  connect-src 'self' data: mediastream: blob: filesystem: 'nonce-YWJjZGVm...' example.com *.sentry.io ...;
  script-src 'self' data: mediastream: blob: filesystem: 'nonce-YWJjZGVm...' example.com *.sentry.io ...;
  style-src 'self' 'unsafe-inline' data: mediastream: blob: filesystem: example.com *.sentry.io ...;
  worker-src 'self' data: mediastream: blob: filesystem: 'nonce-YWJjZGVm...' example.com *.sentry.io ...;
  media-src 'self' data: mediastream: blob: filesystem: 'nonce-YWJjZGVm...' example.com *.sentry.io ...;
  img-src * data: blob:;
  font-src 'self';
  object-src 'none';
  base-uri 'self';
  form-action 'self';
  upgrade-insecure-requests;

X-Frame-Options Behavior by Path

GET /apps           -> X-Frame-Options: DENY
GET /datasets       -> X-Frame-Options: DENY
GET /chat/abc123    -> (no X-Frame-Options header, embeddable)
GET /workflow/def   -> (no X-Frame-Options header, embeddable)
GET /completion/ghi -> (no X-Frame-Options header, embeddable)
GET /webapp-signin  -> (no X-Frame-Options header, embeddable)

Using the Nonce in a Server Component

import { headers } from 'next/headers'

export default async function Page() {
  const nonce = (await headers()).get('x-nonce') ?? undefined
  return (
    <script nonce={nonce} src="/analytics.js" />
  )
}

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment