Skip to content

SOLR-18233 Strengthen Basic Authentication password policy and harden template users created by bin/solr auth enable (take2)#4534

Open
janhoy wants to merge 10 commits into
apache:mainfrom
janhoy:feature/SOLR-18233-strengthen-basicauth
Open

SOLR-18233 Strengthen Basic Authentication password policy and harden template users created by bin/solr auth enable (take2)#4534
janhoy wants to merge 10 commits into
apache:mainfrom
janhoy:feature/SOLR-18233-strengthen-basicauth

Conversation

@janhoy

@janhoy janhoy commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

This is take2, the first PR (#4477) was merged and then reverted. This time around we also modify some tests and add an escape hatch.

What changed

Four related hardening changes to Solr's Basic Authentication:

  1. Password ≠ username enforcement (Sha256AuthenticationProvider): both at login time and when setting a user via set-user (API, Admin UI, CLI), Solr now rejects any credential where the password equals the username. This closes the most common weak-credential pattern where operators set up accounts like admin/admin.

  2. bin/solr auth enable template hardening (security.json, AuthTool): the template shipped with bin/solr auth enable no longer contains pre-hashed passwords for the template users (admin, index, search). Those accounts are created with empty credentials (cannot log in until explicitly assigned a password). The superadmin user and its pre-hashed password are removed entirely. The CLI now prints an explicit reminder after enabling auth that passwords must be set.

  3. Escape hatch for upgrades: a new system property solr.security.auth.basicauth.allowuseraspassword (env SOLR_SECURITY_AUTH_BASICAUTH_ALLOWUSERASPASSWORD) temporarily allows username==password — both at login and user-management time — for operators who need to keep existing user account provisioning working while migrating, such as in test environments.

  4. Security API now returns HTTP 400 on command errors (SecurityConfHandler): a pre-existing bug caused failed set-user (and other security command) operations to return HTTP 200 / status:0 with errors buried in an errorMessages body field, rather than a proper HTTP 400. SecurityConfHandler now throws SolrErrorWrappingException(BAD_REQUEST) on command errors, matching the pattern already used by SchemaHandler and SolrConfigHandler.

Why

Followup to plug the root cause of CVE-2026-44825 and further harden and document the CLI bootstrapping of basic auth.

In particular, the new username==password policy will effectively block attackers attempting to log in as superadmin:superadmin on systems that still have the vulnearble default security.json template even after upgrading solr. This would mitigate the CVE also for users who never read our advisories.

Docs

  • solr-control-script-reference.adoc: expanded bin/solr auth enable section explaining the template users, their roles, and the --block-unknown default.
  • basic-authentication-plugin.adoc: updated intro and added note that set-user rejects username==password.
  • major-changes-in-solr-10.adoc: upgrade note describing the new password policy and the escape hatch.

How to review

  • Core logic: Sha256AuthenticationProvider.java — two small guard blocks (one in authenticate(), one in the set-user command handler). Both gate on SOLR_SECURITY_AUTH_BASICAUTH_ALLOWUSERASPASSWORD.
  • CLI: AuthTool.java — one new guard before writing security.json, and changed blockUnknown handling to only override the template value when explicitly passed.
  • Template: security.json — credentials for admin, index, search are now empty strings; superadmin removed. Make sure it is impossible to log in to these accounts withuot first setting a password.
  • Tests: TestSha256AuthenticationProvider has new tests. Various integration tests updated to use passwords ≠ username.

How to test manually

bin/solr start

# User creation with username==password -> REJECTED
bin/solr auth enable --credentials solr:solr

# Enable auth with a strong password -> OK
bin/solr auth enable --credentials solr:SolrRocks

# Verify set-user rejects username==password via API
curl -u solr:SolrRocks -X POST http://localhost:8983/solr/admin/authentication \
  -H 'Content-Type: application/json' -d '{"set-user": {"bob": "bob"}}'  # → error

# Verify escape hatch works -> allowed to create username==password and to authenticate
bin/solr auth disable --credentials solr:SolrRocks
export SOLR_SECURITY_AUTH_BASICAUTH_ALLOWUSERASPASSWORD=true
bin/solr restart
bin/solr auth enable --credentials solr:solr
curl -I -u solr:solr http://localhost:8983/solr/admin/info/system   # → 200

# Verify that existing user cannot login with username==password without the escape hatch
export SOLR_SECURITY_AUTH_BASICAUTH_ALLOWUSERASPASSWORD=false
bin/solr restart
curl -I -u solr:solr http://localhost:8983/solr/admin/info/system   # → 401

https://issues.apache.org/jira/browse/SOLR-18233

janhoy added 8 commits June 16, 2026 20:27
…sysprop

When the operator sets SOLR_SECURITY_AUTH_BASICAUTH_ALLOWUSERASPASSWORD=true
in the shell running bin/solr, the CLI guard in AuthTool now passes through
username==password credentials, matching the behaviour of the server-side
Sha256AuthenticationProvider. Adds two new tests to AuthToolTest covering
the rejection and escape-hatch paths; also resets ZK security.json before
each test to prevent inter-test interference.
… auth

After "Successfully enabled basic auth with username [X]", now also prints
that user X was assigned the highest access level (superadmin, admin, index,
search), so operators see a complete picture of their security setup alongside
the template user list.
SecurityConfHandler was adding errorMessages to the response body but
returning HTTP 200 / status:0, matching neither the client's expectation
nor the pattern established by SchemaHandler and SolrConfigHandler which
both throw SolrErrorWrappingException(BAD_REQUEST) on command errors.
Align SecurityConfHandler with those handlers so that a failed set-user
(e.g. password == username) returns HTTP 400.  Update SecurityConfHandlerTest
to assert the exception rather than inspecting the response NamedList.

Copilot AI 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.

Pull request overview

This PR hardens Solr’s Basic Authentication by enforcing password != username (with an upgrade escape hatch), removing default usable credentials from the bin/solr auth enable template users, and fixing Security API error signaling to return proper HTTP 400 on command failures.

Changes:

  • Enforce username != password in Sha256AuthenticationProvider for both authentication and set-user, with an escape-hatch sysprop/env var to temporarily allow legacy behavior.
  • Harden bin/solr auth enable by shipping template users with empty credentials and improving CLI messaging; update docs accordingly.
  • Fix Security API command failure handling to return HTTP 400 (throwing SolrErrorWrappingException), and adjust tests to match.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
solr/webapp/web/js/angular/controllers/security.js Adds client-side validation to reject password == username in the Admin UI.
solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/CloudAuthStreamTest.java Updates streaming tests to use passwords that differ from usernames.
solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc Documents the new password policy and the temporary escape-hatch property/env var.
solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc Expands bin/solr auth enable docs and clarifies blockUnknown defaults and template users.
solr/solr-ref-guide/modules/deployment-guide/pages/basic-authentication-plugin.adoc Updates Basic Auth enablement guidance and notes the new set-user restriction.
solr/core/src/test/org/apache/solr/security/TestSha256AuthenticationProvider.java Adds unit tests covering the new policy and escape-hatch behavior.
solr/core/src/test/org/apache/solr/security/BasicAuthOnSingleNodeTest.java Updates test credentials to comply with username != password.
solr/core/src/test/org/apache/solr/security/AuthWithShardHandlerFactoryOverrideTest.java Updates test credentials to comply with username != password.
solr/core/src/test/org/apache/solr/handler/admin/SecurityConfHandlerTest.java Adjusts test expectations for Security API failures now throwing HTTP 400 exceptions.
solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java Updates test credentials to comply with username != password.
solr/core/src/test/org/apache/solr/cli/AuthToolTest.java Adds CLI tests for rejecting/allowing username == password depending on escape hatch.
solr/core/src/resources/security.json Removes pre-hashed template passwords and drops the superadmin template user mapping.
solr/core/src/java/org/apache/solr/security/Sha256AuthenticationProvider.java Implements the username != password enforcement and escape-hatch property lookup.
solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java Throws SolrErrorWrappingException(BAD_REQUEST) on security command errors instead of returning 200 with embedded errors.
solr/core/src/java/org/apache/solr/cli/AuthTool.java Prevents enabling Basic Auth with username == password unless escape hatch is enabled; adjusts blockUnknown handling and CLI output.
changelog/unreleased/SOLR-18233-Strengthen-Basic-Authentication-password-policy.yml Adds an unreleased changelog entry describing the behavior change and escape hatch.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +415 to +419
var username = $scope.upsertUser.username ? $scope.upsertUser.username.trim() : "";
if (password === username) {
$scope.validationError = "Password must not be the same as the username";
return false;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is a fair comment. For operators who wish to disable the rule long-term, it makes sense for the UI to also respect this. Now that the HTTP call made by the UI will fail with HTTP 400, the user will be alerted through the normal error-message mechanism of the UI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I removed the JS enforcement in UI. If the UI now received the HTTP 400 error, it triggered the generic error dialog with an empty message. But now the security page catches the "errorDetail" from requests and displays the error in the security page's existing error dialog, see screenshot
Skjermbilde 2026-06-17 kl  15 06 21

Comment thread solr/core/src/java/org/apache/solr/cli/AuthTool.java
@github-actions github-actions Bot removed the admin-ui label Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants