fix(loginV2): Disable image optimization (#10508)

<!--
Please inform yourself about the contribution guidelines on submitting a
PR here:
https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr.
Take note of how PR/commit titles should be written and replace the
template texts in the sections below. Don't remove any of the sections.
It is important that the commit history clearly shows what is changed
and why.
Important: By submitting a contribution you agree to the terms from our
Licensing Policy as described here:
https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions.
-->

# Which Problems Are Solved

Next.js's Image Optimization feature requires that hostnames for remote
images be explicitly defined in the `next.config.js` file via
`remotePatterns`. This configuration is static and evaluated at **build
time**.

However, the `ZITADEL_API_URL`, which is supposed to be used for
additional whitelisted hostnames, is a dynamic environment variable only
known at **run time**. This creates a fundamental conflict, making it
impossible to add the user-provided URL to the configuration when
building the public Docker image. Consequently, images like instance
logos fail to load.

The existing workaround uses a permissive wildcard pattern
(`*.zitadel.*`). This is a significant security risk, as it could allow
malicious actors to abuse the server as an open image-resizing proxy,
leading to potential denial-of-service (DDoS) attacks or excessive
costs.

# How the Problems Are Solved

This change disables the Next.js Image Optimization feature entirely by
setting `unoptimized: true` in the `images` configuration.

By doing this, Next.js will no longer attempt to optimize, cache, or
validate remote image sources. Instead, it will pass the original image
URL directly to the client. This approach resolves the issue by:

1. **Eliminating the need for `remotePatterns`**, which bypasses the
build-time vs. run-time configuration conflict.
2. **Improving security** by removing the overly permissive wildcard
pattern.
3.  **Ensuring functionality**, as remote images now load correctly.

The trade-off is the loss of performance benefits from Next.js image
optimization, but I see this as an acceptable compromise to restore
essential functionality and secure the application.


Fixes #10456

Co-authored-by: Max Peintner <max@caos.ch>
This commit is contained in:
Nils
2025-08-25 16:53:21 +03:00
committed by GitHub
parent b23c0bc6ad
commit 7a9cc5c456

View File

@@ -33,30 +33,6 @@ const secureHeaders = [
{ key: "X-Frame-Options", value: "deny" },
];
const imageRemotePatterns = [
{
protocol: "http",
hostname: "localhost",
port: "8080",
pathname: "/**",
},
{
protocol: "https",
hostname: "*.zitadel.*",
port: "",
pathname: "/**",
},
];
if (process.env.ZITADEL_API_URL) {
imageRemotePatterns.push({
protocol: "https",
hostname: process.env.ZITADEL_API_URL?.replace("https://", "") || "",
port: "",
pathname: "/**",
});
}
const nextConfig = {
basePath: process.env.NEXT_PUBLIC_BASE_PATH,
output: process.env.NEXT_OUTPUT_MODE || undefined,
@@ -65,7 +41,7 @@ const nextConfig = {
dynamicIO: true,
},
images: {
remotePatterns: imageRemotePatterns,
unoptimized: true
},
eslint: {
ignoreDuringBuilds: true,