
Step-by-step lab writeup demonstrating CVE-2019-20933 InfluxDB authentication bypass via forged JWT tokens, including exploitation, post-exploitation, and remediation guidance.
Starting with what is running in the environment. I list all active containers:
docker ps

The victim exposes a single port: 8086.
Currently, I do not have detailed information about the target. From the docker ps output, the system only exposes one notable service externally at port 8086, which is mapped to the service inside the container. This is the primary attack surface to analyze.
Instead of accessing it immediately via browser, we proceed to fingerprint the service using Nmap to determine what service is running on port 8086:
nmap -sV -sC -p 8086 192.168.3.137

The scan results show that port 8086 is the HTTP service of InfluxDB OSS 1.6.6. This is a time-series database exposed via an HTTP API, not a typical web application.
InfluxDB is an open-source Time Series Database (TSDB) written in Go. Unlike RDBMS (optimized for precise transactions) or Elasticsearch (optimized for text search), InfluxDB was created with a single purpose: Handling massive write volumes (High Write Throughput) and querying data along the time axis with low latency.

Since the service has been fingerprinted as InfluxDB, the next step is to reference how InfluxDB communicates with clients. According to the InfluxDB v1 HTTP API documentation, port 8086 is the default HTTP API port. Important endpoints include:
/ping: checks the operational status of the server./query: sends InfluxQL queries to read metadata or data./write: writes time-series data into the database.⇒ Thinking: After Nmap identifies the service as InfluxDB http admin 1.6.6, we do not continue testing it like a standard website. For web applications, we typically look for routes, login forms, or directories. However, with InfluxDB, the attack surface lies within the HTTP API. Therefore, we need to switch to testing the standard InfluxDB API endpoints to determine if the API requires authentication. Consequently, the next testing direction is not to access / via browser, but to send requests directly to the API endpoints of InfluxDB.
/ping EndpointAfter identifying port 8086 as the InfluxDB HTTP API, check the /ping endpoint to confirm the service is operational:
curl -i <http://192.168.3.137:8086/ping>

Response 204 No Content confirms that InfluxDB is operating normally. The headers further confirm the service version as InfluxDB OSS 1.6.6
/query Endpointcurl -i -s "http://192.168.3.137:8086/query?q=SHOW+DATABASES"

The /query endpoint does not allow direct queries without authentication credentials. This confirms that InfluxDB has authentication enabled and blocks all anonymous queries sent to the system.
I switch to thinking: does InfluxDB version 1.6.6 have any vulnerability that allows bypassing the authentication mechanism?

By referencing public vulnerability databases, InfluxDB versions prior to 1.7.6 are affected by CVE-2019-20933. This is an Authentication Bypass vulnerability within InfluxDB's authentication function, related to handling JWT tokens with an empty shared secret.
Since the target is running InfluxDB 1.6.6, which is lower than the patched version 1.7.6, the service falls within the affected version range.
It can be concluded:
Service: InfluxDB OSS
Version: 1.6.6
Authentication: Enabled
CVE mapping: CVE-2019-20933
Impact: Authentication Bypass
Status: Version vulnerable
⇒ Thinking: Initially, the /query endpoint returns 401 Unauthorized, indicating that the authentication mechanism is active. However, having authentication enabled does not mean absolute security. When the version is fingerprinted as 1.6.6, we need to correlate it with known CVEs. The results indicate that this version falls within the range affected by CVE-2019-20933, meaning it is possible to bypass the authentication mechanism protecting the /query endpoint. Based on these identification results, the exploitation phase will focus on verifying CVE-2019-20933 by generating an appropriate JWT token to bypass authentication and execute queries against the /query endpoint.
The CVE-2019-20933 vulnerability occurs in the authenticate function within the services/httpd/handler.go file of InfluxDB prior to version 1.7.6.
InfluxDB supports authentication using JSON Web Tokens (JWT) for HTTP API requests. Upon receiving a request with the header:
Authorization: Bearer <token>
InfluxDB will perform the following steps:
shared-secret configuration value from the influxdb.conf file to act as the secret key for token signature verification.username field from the claims to determine the user executing the query.In the affected versions, if JWT authentication is enabled but the shared-secret parameter is not configured, the secret value may be processed as an empty string ("").
The system fails to adequately validate the security strength of the secret before verifying the JWT signature. This allows an attacker to construct a custom JWT, sign it with an empty secret, and then set the username claim to a valid account on the system, such as admin if this account exists in the lab.
When this token is submitted via the Authorization: Bearer <token> header, InfluxDB uses the same empty secret to verify the signature. If the signature matches and the username exists, the request will be authorized without requiring the user's actual password.
The processing flow can be summarized as follows:
| Step | Normal Processing | Flaw in CVE-2019-20933 |
|---|---|---|
| 1 | Client sends Authorization: Bearer <token> | Attacker self-creates a JWT |
| 2 | Server reads shared-secret from configuration | shared-secret is not set |
| 3 | Server uses secret to verify JWT signature | Secret is processed as an empty string "" |
| 4 | If token is valid, retrieve username from claim | Attacker sets username=admin if user exists |
| 5 | Server grants permissions based on the claim user | Request is accepted without requiring a password |
Exploitation flow at the logic level:
InfluxDB < 1.7.6
→ authentication enabled
→ empty shared-secret
→ attacker creates JWT signed with secret ""
→ sends token via Authorization: Bearer
→ server accepts the token
→ query to /query succeeds
After understanding the CVE mechanism, it is necessary to correlate it with the target to avoid drawing conclusions solely based on version.