Keypoints
- Dappnode contained multiple web-based vulnerabilities (pre-auth XSS, local file disclosure, post-auth command injection) that enabled remote compromise.
- An IPFS proxy in Dappnode allowed reflected XSS via my.dappnode/ipfs, serving attacker-controlled content to operators.
- Command injection in the Dappmanager container plus access to the Docker socket enabled container breakout and root shells on hosts.
- WireGuard API had a local file disclosure and permissive CORS, permitting exfiltration of VPN client/server profiles.
- Orbit Bridge analysis identified exposed validator APIs and a public validate path that could reveal V/R/S signature values on-chain, enabling signature replay across chains.
- Private keys in validator deployments were stored/expected in plaintext and the same key appeared reused across supported chains, increasing risk.
MITRE Techniques
- [T1190] Exploit Public-Facing Application – Validator and management APIs lacked access control and were callable over the network, enabling abuse of API routes: (‘the validator itself does not implement any kind of access control for the APIs. Deploying the validator container exposes the API on port 17090 of the host system’).
- [T1059.004] Command and Scripting Interpreter: Unix Shell – Post-auth command injection in Dappmanager allowed execution in container context and, via Docker socket, host shell access: (‘a reverse TCP shell was executed with root privileges on the host Dappnode system upon the victim visiting the malicious URL’).
- [T1005] Data from Local System – Local file disclosure in the WireGuard API allowed attackers to read and leak VPN client/server configuration files: (‘results in their Dappnode client and server WireGuard VPN credentials being exfiltrated to an attacker’s web server’).
- [T1552.001] Unsecured Credentials: Credentials in Files – Validator private key expected in plaintext in configuration, exposing signing keys if accessed: (‘.example.env … VALIDATOR_PK= … Testing showed that the private key was expected in plaintext format’).
- [T1078] Valid Accounts – Attackers leveraged valid validator signatures (V/R/S) to authorize withdrawals and replayed those signatures across chains: (‘signatures provided by the attacker can be confirmed to originate of Orbit Bridge validators via the following Forge proof-of-concept test suite’).
Indicators of Compromise
- [Domain] Dappnode management/UI – my.dappnode (IPFS proxy endpoint: my.dappnode/ipfs)
- [Repository/Codebase] Validator and bridge code referenced – bridge-dockerize (validator container repo), bridge-contract (Vault contract repo)
- [API endpoints] Validator and management routes – /validate/:migAddr/:sigHash, /getTransaction/:chain/:migAddr/:transactionId, /confirm/:chain/:migAddr/:transactionId/:gasPrice/:chainId
- [File/Config] Plaintext private key in environment – .example.env containing VALIDATOR_PK (and other env entries)
- [Contract/storage] Vault contract public mappings exposing signature components – OrbitVault public vSig/rSig/sSig mappings (used to read V/R/S values)
<li/[Port] Exposed validator service – port 17090 (validator API exposed via Docker bridge network)
Researchers reproduced two practical exploitation chains against Dappnode: (1) an IPFS-proxy reflected XSS served from my.dappnode/ipfs that, when visited by an authenticated operator, executed JavaScript to trigger a management API call with a command-injection payload in Dappmanager; because Dappmanager had access to the host Docker socket, the injected command could launch a container with host mounts and obtain a root shell, demonstrating a single-click remote takeover. (2) A local file disclosure in the WireGuard package combined with a permissive CORS policy allowed attacker-controlled web origins (weaponizing the XSS) to retrieve WireGuard client and server profiles and exfiltrate them to an external endpoint, enabling persistent VPN access into the operator’s local network.
For the Orbit Bridge incident, analysis of the public bridge-dockerize validator code and OrbitVault contracts shows a plausible off-chain-to-on-chain pivot: the validator API accepted arbitrary multisig addresses and sigHash values without strict verification, used the validator private key to sign the supplied sigHash, then called a public validate function that stored V/R/S values on the OrbitChain Vault contract. Because the same validator keys appeared reused across chains and the OrbitVault exposed signature mappings publicly, an attacker could generate arbitrary transaction hashes, use the validator API to have those hashes signed and posted on-chain, then read the resulting V/R/S values and supply them to withdraw() calls on other chain Vault contracts to authorize transfers.
Mitigations include removing or tightly restricting public access to validator/management APIs, enforcing strict input validation and contract-level binding between message contents and signatures, avoiding reuse or plaintext storage of validator private keys, eliminating public getters that expose raw signature components, and performing holistic audits that include web2 components (APIs, CORS, container privileges) alongside smart contract logic.
Read more: https://www.netspi.com/blog/technical/blockchain-penetration-testing/web2-bugs-in-web3-systems/