Skip to content

fix(security): reject actuator basic-auth when internal password is unset (GHSA-xfc5-796c-7hr9)#41964

Merged
wyattwalter merged 2 commits into
releasefrom
ww-ghsa-actuator-internal-password
Jul 9, 2026
Merged

fix(security): reject actuator basic-auth when internal password is unset (GHSA-xfc5-796c-7hr9)#41964
wyattwalter merged 2 commits into
releasefrom
ww-ghsa-actuator-internal-password

Conversation

@wyattwalter

@wyattwalter wyattwalter commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

The /actuator/** management endpoints are protected by HTTP Basic auth that compares the supplied password against APPSMITH_INTERNAL_PASSWORD. That variable defaults to an empty string when unset (application-ce.properties: appsmith.internal.password=${APPSMITH_INTERNAL_PASSWORD:}), so the check "".equals("") succeeds for any request sending empty Basic Auth credentials — granting the INTERNAL authority and bypassing authentication on the actuator endpoints.

This guards the comparison so an unset/empty configured password never authenticates any caller. All /actuator/** requests then return 401 until an operator explicitly sets APPSMITH_INTERNAL_PASSWORD.

Why it matters

  • On a default deployment the exposed actuator surface is prometheus and metrics (per application-ee.properties), plus health on CE — so the practical pre-fix impact is unauthenticated read access to operational metrics, not secrets.
  • Impact escalates if an operator widens management.endpoints.web.exposure.include (e.g. to include env/heapdump).
  • Ref: GHSA-xfc5-796c-7hr9 (and duplicate GHSA-8pr2-629w-7q87).

Change

Single-file change in SecurityConfig.internalWebFilterChain. No new imports (uses String.isEmpty()), so the hunk applies cleanly to EE via the hourly sync.

Testing

  • Before: curl -u 'anyuser:' https://<host>/actuator/prometheus200
  • After: same request → 401; 200 only when APPSMITH_INTERNAL_PASSWORD is set and matched.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved access handling for internal actuator endpoints when basic authentication credentials are empty or missing.
    • Prevented empty or unset internal passwords from being treated as a valid match, so requests now correctly follow the unauthenticated path when no valid credentials are configured.

Warning

Tests have not run on the HEAD 2b58fc3 yet


Wed, 08 Jul 2026 02:34:56 UTC

…nset (GHSA-xfc5-796c-7hr9)

The /actuator/** filter chain compared the supplied Basic Auth password
against APPSMITH_INTERNAL_PASSWORD, which defaults to an empty string when
unset. "".equals("") then matched for any request carrying empty Basic Auth
credentials, granting the INTERNAL authority and bypassing authentication on
the actuator endpoints (reachable on backend port 8080 in Kubernetes
deployments).

Guard the comparison so an unset/empty configured password never authenticates
any caller; all /actuator/** requests then correctly return 401 until an
operator sets APPSMITH_INTERNAL_PASSWORD.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The /actuator/** Basic Auth check now requires INTERNAL_PASSWORD to be set and non-empty before matching credentials, so empty or unset passwords no longer grant the internal authority path.

Changes

Security config fix

Layer / File(s) Summary
Actuator credential validation guard
app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java
Adds a non-null and non-empty guard on INTERNAL_PASSWORD before the credentials comparison, otherwise returning the unauthenticated token path.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

A gate once blinked at empty keys,
Now only real secrets pass with ease.
The actuator stands more tight,
With blank passwords out of sight.
🔒

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is detailed, but it omits required template sections like Fixes, Automation, and Communication. Add the issue reference, /ok-to-test tag, Cypress results section if applicable, and the Communication checkbox section.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly matches the security fix for rejecting actuator basic-auth when the internal password is unset.
✨ 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-actuator-internal-password

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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@wyattwalter wyattwalter requested a review from subrata71 July 8, 2026 15:55

@salevine salevine left a comment

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.

  1. No regression test for a published GHSA (flagged by all four reviewers). The repo already has the exact pattern to copy: AuthGuardTest.java in appsmith-server/src/test/.../configurations/, itself created for a prior security fix. Recommended: an ActuatorAuthTest with two contexts — password unset (empty Basic creds → 401) and password set (wrong → 401, correct → 200, no header → 401). Notably, the "password set + correct creds still works" leg has no validation anywhere, including the author's manual curl.
  2. Release note needed. Deployments that scrape /actuator/prometheus relying on the empty-password hole will start getting 401s. That's the intended fail-closed outcome, but operators need to be told to set APPSMITH_INTERNAL_PASSWORD rather than work around it.
    Tracked (follow-up hardening, not this PR): (edited)

@wyattwalter wyattwalter merged commit ea8e041 into release Jul 9, 2026
19 checks passed
@wyattwalter wyattwalter deleted the ww-ghsa-actuator-internal-password branch July 9, 2026 21:28
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.

3 participants