Threats tagged 'ghsa-2j95-gqxf-v3vg'
1 threat
Most recently published first
| Severity | CVSS | Signals | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|---|
| Critical | 9.4 | EPSS 0.2% | CVE-2026-11746LY Central Dogma · CWE-798 Critical9.4EPSS 0.2%CVE Database V5CVE-2026-11746 ## Vulnerability `ZooKeeperReplicationConfig.secret()` silently substitutes the hard-coded constant `"ch4n63m3"` (leetspeak for "change me") whenever the operator omits `replication.secret`. The same secret is wired into both the **client-facing SASL context** and the **quorum/learner SASL contexts** of the embedded ZooKeeper. The constant is in OSS source on GitHub and is discoverable via code search in seconds. ### Three Reinforcing Defects 1. **OSS-public credential** — `DEFAULT_SECRET` is in `line/centraldogma` source. 2. **Silent fallback** — `firstNonNull(convertValue(...), DEFAULT_SECRET)` substitutes the default with no log, no warning, no startup banner. The only sanity check `checkArgument(!secret().isEmpty(), ...)` passes because the getter substitutes the literal before the emptiness check runs. 3. **Dual-purpose secret** — used for both ZK client-port super auth and inter-peer quorum SASL. A single leaked password authenticates against both surfaces. ### Architecture Context (Important) Central Dogma does **NOT** connect to an external ZooKeeper ensemble. Each replica embeds a `QuorumPeer` (`EmbeddedZooKeeper extends QuorumPeer`) inside its own JVM. The Central Dogma cluster **IS** the ZK ensemble. So the "ZK network" is the inter-replica network of the Central Dogma cluster itself. ### Applicability | `replication.method` | ZK Started? | Applicable? | |---|---|---| | `NONE` (standalone, dev default) | No | **NOT applicable** | | `ZOOKEEPER` (HA production) | Yes, embedded on every replica | **Fully applicable** — canonical production configuration | --- ## Evidence **File:** `server/src/main/java/com/linecorp/centraldogma/server/ZooKeeperReplicationConfig.java` **Branch:** `main` @ commit `d64a5151` **Line 53** — the constant: ```java private static final String DEFAULT_SECRET = "ch4n63m3"; ``` **Lines 210–215** — the silent fallback: ```java /** * Returns the secret string used for authenticating the ZooKeeper peers. */ public String secret() { return firstNonNull(convertValue(secret, "replication.secret"), DEFAULT_SECRET); } ``` --- **File:** `server/src/main/java/com/linecorp/centraldogma/server/internal/replication/ZooKeeperCommandExecutor.java` **Lines 586–607** — JAAS wiring (same secret on both surfaces): ```java final String escapedSecret = jaasValueEscaper.escape(cfg.secret()); ImmutableList.of("Server", EmbeddedZooKeeper.SASL_SERVER_LOGIN_CONTEXT).forEach(name -> { buf.append(name).append(" {").append(newline); buf.append(DigestLoginModule.class.getName()).append(" required").append(newline); buf.append("user_super=\"").append(escapedSecret).append("\";").append(newline); buf.append("};").append(newline); }); ImmutableList.of("Client", EmbeddedZooKeeper.SASL_LEARNER_LOGIN_CONTEXT).forEach(name -> { buf.append(name).append(" {").append(newline); buf.append(DigestLoginModule.class.getName()).append(" required").append(newline); buf.append("username=\"super\"").append(newline); buf.append("password=\"").append(escapedSecret).append("\";").append(newline); buf.append("};").append(newline); }); ``` --- **File:** `server/src/main/java/com/linecorp/centraldogma/server/internal/replication/EmbeddedZooKeeper.java` **Line 44** — proves CD embeds the ZK server: ```java final class EmbeddedZooKeeper extends QuorumPeer { ``` **Lines 213–220** — client port binding (loopback only): ```java private static ServerCnxnFactory createCnxnFactory(QuorumPeerConfig zkCfg) throws IOException { final InetSocketAddress bindAddr = zkCfg.getClientPortAddress(); final ServerCnxnFactory cnxnFactory = ServerCnxnFactory.createFactory(); // Listen only on 127.0.0.1 because we do not want to expose ZooKeeper to others. cnxnFactory.configure(new InetSocketAddress("127.0.0.1", bindAddr != null ? bindAddr.getPort() : 0), zkCfg.getMaxClientCnxns()); return cnxnFactory; } ``` > Quorum/election ports are **NOT** loopback-bound — they bind to `replication.servers[].host` as configured, exposed on the inter-replica network. --- ## PoC Two attack surfaces, two scenarios. **Surface A** (client port, same-host) is implemented as a working read-only PoC. **Surface B** (quorum-port peer impersonation) is documented but intentionally not weaponized. ### Surface A — Same-Host Client Port (Loopback) PoC Python + kazoo + pure-sasl. Authenticates as `super` over SASL DIGEST-MD5 with the leaked secret and reads the full Central Dogma replication log. Hardcoded to `127.0.0.1`, read-only, prints first 5 entries. ```python #!/usr/bin/env python3 """ C3 PoC -- ZooKeeper default-secret takeover (read-only, loopback only). Demonstrates that a Central Dogma instance launched with a ZooKeeper-replicated configuration but without `replication.secret` set exposes its embedded ZooKeeper to anyone with local-host access, using the well-known credential `super / ch4n63m3`. SAFETY: * Hardcoded to 127.0.0.1. Refuses any other targ | CVE Database V5 |
Page 1 of 1