Slash & Burn: Bypassing Apache Solr Authorization with a Single Character
Jan 22, 2026·6 min read·4 visits
Executive Summary (TL;DR)
Apache Solr versions 5.3.0 through 9.10.0 contain a 'fail-open' authorization vulnerability. If a deployment uses the `RuleBasedAuthorizationPlugin` without a catch-all `all` permission rule, attackers can bypass specific permission checks (like `security-read`) by appending a trailing slash to the request path. This exploits a normalization inconsistency where Solr fails to match the path to a permission, returns 'null', and subsequently allows the request.
A critical logic flaw in Apache Solr's RuleBasedAuthorizationPlugin allows remote attackers to bypass access controls on administrative endpoints. By simply appending a trailing slash or manipulating path parameters, attackers can trick the authorization mechanism into failing open, granting access to sensitive configuration and security data.
The Hook: Solr's Glass Fortress
Apache Solr is the massive, beating heart of enterprise search. It indexes everything from your emails to your shopping history. Naturally, because it holds the keys to the data kingdom, it comes with a locking mechanism: the RuleBasedAuthorizationPlugin. This plugin is supposed to be the bouncer, checking your ID (credentials) against the guest list (security.json) before letting you into the VIP section (the Admin API).
Administrators spend hours crafting granular security.json files. They define roles like dev-ops, read-only, and security-admin. They map these roles to permissions like config-edit or security-read. It looks robust. It feels secure. You deploy it, pat yourself on the back, and go grab a coffee.
But here's the kicker: Solr's bouncer has a blind spot. It assumes that every request will neatly fit into a predefined category. CVE-2026-22022 is the story of what happens when you hand the bouncer a ticket written in crayons that simply says 'null'. Instead of kicking you out, the bouncer gets confused, shrugs, and holds the door open for you.
The Flaw: The Sound of One Hand Shrugging
To understand this vulnerability, you have to understand how Solr decides what you are trying to do. When a request hits the server, Solr's handlers (like ZookeeperInfoHandler or SolrConfigHandler) inspect the path and HTTP method to determine the required permission. For example, a GET request to /solr/admin/security.json should map to the security-read permission.
However, prior to version 9.10.1, this logic was brittle. It relied on exact string matching without sufficient normalization. If you requested /solr/admin/security.json (clean path), the handler said, "Aha! You need security-read permissions."
But if you requested /solr/admin/security.json/ (trailing slash), the logic faltered. The handler compared /security.json/ against /security.json, saw they didn't match, and failed to identify the correct permission name.
In a secure system, failing to identify the permission should result in an error or a default-deny. In Solr's RuleBasedAuthorizationPlugin, the handler returned null. The plugin then looked at your security.json rules. If you didn't have a catch-all rule (the all permission) defined, the plugin essentially said, "Well, I don't have a rule for 'null', so I guess you're free to go." It is a classic 'Fail-Open' architecture flaw.
The Code: Patch Analysis
The fix, authored by Jason Gerlowski in commit c135e6335c7158fa26e96b0dc386f825255b47c0, reveals the embarrassment of the original logic. The patch applies a tourniquet in two places: normalizing the input and changing the default behavior from "shrug" to "panic".
First, they forced path normalization in HttpSolrCall and V2HttpCall using StringUtils.stripEnd(path, "/"). This ensures that /path/ and /path are treated identically before the permission check happens.
Second, and more critically, they patched the RuleBasedAuthorizationPluginBase.java to handle the null case explicitly. Look at the diff logic below:
// RuleBasedAuthorizationPluginBase.java (The Fix)
PermissionNameProvider handler = (PermissionNameProvider) context.getHandler();
PermissionNameProvider.Name permissionName = handler.getPermissionName(context);
// The new safety net
if (permissionName == null) {
final var errorMessage =
String.format(
Locale.ROOT,
"Unable to find 'predefined' associated with requestHandler [%s] and request [%s %s]",
handler.getClass().getName(),
context.getHttpMethod(),
context.getResource());
// SCREAM AND DIE instead of failing open
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, errorMessage);
}Before this patch, that if (permissionName == null) block didn't exist. The code would just proceed, bypassing the specific checks for security-read or config-read, leaving the door wide open if the all permission wasn't manually configured by the admin.
The Exploit: Slashing the ACLs
Exploiting this is trivially easy and embarrassingly effective. It requires no compiled code, no heap grooming, and no race conditions. It just requires a browser or curl and a basic understanding of URL structures.
The Scenario: You are targeting a Solr instance protected by basic auth. You have valid low-level credentials (or no credentials, if the endpoint is exposed), but you want to read the security.json file to dump the password hashes of the administrators.
Step 1: The Denial
Attempt to read the security config normally:
GET /solr/admin/zookeeper?path=/security.json
Result: 403 Forbidden (You don't have the security-read role).
Step 2: The Bypass
Append a slash to the path parameter:
GET /solr/admin/zookeeper?path=/security.json/
The Logic Flow:
- The
ZookeeperInfoHandlerreceives the path/security.json/. - It checks:
if ("/security.json".equals(path)). Result:false. - It falls through its logic and returns
nullfor the permission name. RuleBasedAuthorizationPluginreceivesnull.- It iterates through defined rules in
security.json(config-edit,security-read). None matchnull. - No
allrule exists? Access Granted.
This technique works on various handlers where path normalization was skipped, effectively rendering the granular ACLs useless.
The Impact: Keys to the Kingdom
Why is this a CVSS 8.2 and not just a nuisance? Because in Solr, configuration is everything. If an attacker can bypass the security-read check, they can download security.json. This file often contains the salted hashes of all users, including administrators.
With the hashes in hand, an offline brute-force attack (or simply passing the hash if the attacker can manipulate internal states) leads to full administrative takeover. Once an attacker is an Admin, they can abuse the ConfigHandler to load malicious .jar files or use Velocity templates to achieve Remote Code Execution (RCE).
Furthermore, this bypass isn't limited to security configs. It allows reading schema definitions (schema-read) and metrics (metrics-read), potentially exposing business logic and infrastructure details that facilitate further attacks. It turns a locked door into a revolving door.
The Fix: Closing the Loophole
The immediate fix is to upgrade to Apache Solr 9.10.1. This version includes the patch that forces normalization and throws exceptions on ambiguous requests.
If you cannot upgrade immediately (and let's be honest, who upgrades enterprise search clusters on a Friday?), you have a configuration-based mitigation. You must update your security.json to include a catch-all rule.
Add a permission rule for all and assign it to a restricted role (or your admin role). This effectively changes the default behavior from "Allow" to "Deny".
{
"name": "all",
"role": "admin" // or a specific safe role
}With this rule in place, when the exploit returns null (or any unknown permission), the plugin will fall through to the all rule, check if the user has the admin role, and correctly deny the request. It's the digital equivalent of nailing the window shut because the lock is broken.
Official Patches
Fix Analysis (1)
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:NAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
Apache Solr Apache Software Foundation | >= 5.3.0, <= 9.10.0 | 9.10.1 |
| Attribute | Detail |
|---|---|
| CVE ID | CVE-2026-22022 |
| CVSS v3.1 | 8.2 (High) |
| CWE | CWE-285 (Improper Authorization) |
| Attack Vector | Network (API) |
| Exploit Complexity | Low |
| Privileges Required | None / Low (depending on network access) |
| Status | Patched |
MITRE ATT&CK Mapping
The software does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action.
Known Exploits & Detection
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.