Skip to content

fix(security): bind Caddy admin to local socket (GHSA-8jvv-gwqg-6vjc)#41847

Merged
wyattwalter merged 2 commits into
releasefrom
ww-ghsa-caddy-admin
May 26, 2026
Merged

fix(security): bind Caddy admin to local socket (GHSA-8jvv-gwqg-6vjc)#41847
wyattwalter merged 2 commits into
releasefrom
ww-ghsa-caddy-admin

Conversation

@wyattwalter
Copy link
Copy Markdown
Contributor

@wyattwalter wyattwalter commented May 26, 2026

Summary

Security fix for GHSA-8jvv-gwqg-6vjc. Caddy's admin endpoint now binds to a Unix socket instead of TCP; Prometheus metrics keep their previous port for scrape-config compatibility.

What changed

deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs — admin moved to a Unix socket, dedicated :2019 { metrics } block for Prometheus, no Helm changes.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Admin interface now binds to a local Unix socket instead of a network port, reducing external exposure.
    • Port 2019 is reserved exclusively for Prometheus metrics collection to isolate monitoring traffic.
    • HTTP protocol handling and trusted-proxy/rate-limiting settings in the admin configuration have been tightened for improved security and reliability.

Review Change Stack

Warning

Tests have not run on the HEAD c49fba7 yet


Tue, 26 May 2026 18:54:36 UTC

Caddy's admin endpoint now binds to a Unix socket so it is not
reachable over TCP. Prometheus metrics move to a dedicated server
block on :2019 so the existing Helm service-metrics keeps working.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@wyattwalter
Copy link
Copy Markdown
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions
Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/26465840382.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41847.
recreate: .
base-image-tag: .

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Walkthrough

The Caddy configuration generator now derives a Unix socket path from TMP for the admin interface and creates a dedicated :2019 site to serve Prometheus metrics, while keeping explicit HTTP protocols, trusted proxies, and conditional rate limiting.

Changes

Caddy Admin and Metrics Configuration

Layer / File(s) Summary
Admin socket and dedicated metrics endpoint
deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs
Adds CaddyAdminSocketPath (from process.env.TMP) and updates the generated Caddyfile to bind the admin interface to admin unix/${CaddyAdminSocketPath} and to host Prometheus metrics on a separate :2019 site. HTTP/1-3, trusted proxies, and conditional rate-limiting remain configured.

Sequence Diagram(s)

sequenceDiagram
  participant Generator as caddy-reconfigure.mjs
  participant CaddyAdminSocket as unix/CaddyAdminSocket
  participant MetricsSite as :2019
  Generator->>CaddyAdminSocket: write admin unix socket path (CaddyAdminSocketPath)
  Generator->>MetricsSite: configure site to serve prometheus `metrics` on all routes
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

Security

Suggested reviewers

  • subrata71

Poem

⚙️ A socket hums where admin sleeps,
Port two-zero-one-nine watches and keeps,
Metrics march out on a single lane,
Config split tidy, quiet, and sane.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description provides a clear summary of the security fix, explains what changed, and references the advisory; however, it lacks the issue link format and doesn't address the required template sections (Fixes #, Communication checkbox). Add 'Fixes GHSA-8jvv-gwqg-6vjc' or link to the issue/advisory at the top, and complete the Communication section with a checkbox selection.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main security change: binding Caddy admin to a local socket instead of TCP, with reference to the specific vulnerability advisory.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ww-ghsa-caddy-admin

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

Deploy-Preview-URL: https://ce-41847.dp.appsmith.com

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs (1)

45-46: ⚡ Quick win

Derive the admin socket path from the same temp root.

CaddyfilePath comes from process.env.TMP, but the new admin socket is hard-coded under /tmp/appsmith. Keeping both under the same base avoids hidden coupling and makes the directory creation at Line 220 cover the socket path too.

♻️ Suggested cleanup
 const CaddyfilePath = process.env.TMP + "/Caddyfile"
+const CaddyAdminSocketPath = process.env.TMP + "/caddy.sock"
 ...
-  admin unix//tmp/appsmith/caddy.sock
+  admin unix/${CaddyAdminSocketPath}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs` around lines 45 - 46,
The admin socket path is hard-coded as "unix//tmp/appsmith/caddy.sock" while
CaddyfilePath derives its base from process.env.TMP; change the admin socket to
be derived from the same TMP root (use the base from CaddyfilePath or
process.env.TMP) so both use the same temp root, and update the
directory-creation logic that currently creates the TMP root directory to also
ensure the socket directory exists; reference the CaddyfilePath variable and
replace the literal "unix//tmp/appsmith/caddy.sock" with a path built from that
TMP root.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs`:
- Around line 45-46: The admin socket path is hard-coded as
"unix//tmp/appsmith/caddy.sock" while CaddyfilePath derives its base from
process.env.TMP; change the admin socket to be derived from the same TMP root
(use the base from CaddyfilePath or process.env.TMP) so both use the same temp
root, and update the directory-creation logic that currently creates the TMP
root directory to also ensure the socket directory exists; reference the
CaddyfilePath variable and replace the literal "unix//tmp/appsmith/caddy.sock"
with a path built from that TMP root.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e2fb25ad-b1c7-4fab-a6cf-73353e22c206

📥 Commits

Reviewing files that changed from the base of the PR and between d6d749e and 131d402.

📒 Files selected for processing (1)
  • deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs

Both CaddyfilePath and the socket now share a single source of truth
(process.env.TMP) so they stay aligned if the temp root ever moves.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@wyattwalter
Copy link
Copy Markdown
Contributor Author

/build-deploy-preview skip-tests=true recreate=true

@github-actions
Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/26468640489.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41847.
recreate: true.
base-image-tag: .

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs (1)

224-224: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid/un-gate the unconditional caddy reload in caddy-reconfigure.mjs (current --address concern is likely overstated)

caddy-reconfigure.mjs runs spawnSync(... ["reload","--config", CaddyfilePath]) right after writing the Caddyfile, but the container entrypoint calls node caddy-reconfigure.mjs before starting Caddy—so this reload is unnecessary and can fail silently (return value isn’t checked). The specific claim that it will always hit localhost:2019 due to missing --address doesn’t match how caddy reload --config determines the admin endpoint (it should use the admin settings from the provided config, falling back to localhost:2019 only when not derivable). Remove the reload from caddy-reconfigure.mjs, or gate it / check spawnSync results and only run reload when Caddy is already running.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs` at line 224, The
unconditional call to spawnSync(AppsmithCaddy, ["reload", "--config",
CaddyfilePath]) in caddy-reconfigure.mjs is unsafe because the script runs
before Caddy is started; remove this unconditional reload or gate it by
detecting a running Caddy instance (e.g., attempt a lightweight check against
the admin endpoint or test spawnSync(AppsmithCaddy, ["status"])/inspect its exit
code) and only call spawnSync(... ["reload", "--config", CaddyfilePath]) when
that check indicates Caddy is active; if you keep the reload, capture and check
spawnSync’s return value (status, stdout/stderr) and log or surface failures
instead of ignoring them (referencing spawnSync, AppsmithCaddy, and
CaddyfilePath to locate the call).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs`:
- Line 224: The unconditional call to spawnSync(AppsmithCaddy, ["reload",
"--config", CaddyfilePath]) in caddy-reconfigure.mjs is unsafe because the
script runs before Caddy is started; remove this unconditional reload or gate it
by detecting a running Caddy instance (e.g., attempt a lightweight check against
the admin endpoint or test spawnSync(AppsmithCaddy, ["status"])/inspect its exit
code) and only call spawnSync(... ["reload", "--config", CaddyfilePath]) when
that check indicates Caddy is active; if you keep the reload, capture and check
spawnSync’s return value (status, stdout/stderr) and log or surface failures
instead of ignoring them (referencing spawnSync, AppsmithCaddy, and
CaddyfilePath to locate the call).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 16be9311-bb45-409d-8f0d-c5ab268fd30e

📥 Commits

Reviewing files that changed from the base of the PR and between 131d402 and c49fba7.

📒 Files selected for processing (1)
  • deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs

@wyattwalter wyattwalter merged commit b36830e into release May 26, 2026
20 checks passed
@wyattwalter wyattwalter deleted the ww-ghsa-caddy-admin branch May 26, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants