Introduction
We express our gratitude to the Zcash team for the collaborative engagement that enabled the execution of this dApp Security Assessment.
ChainSafe is a blockchain R&D firm focused on interoperable, open-source tooling. WebZjs clients are typically web and browser-based wallet developers building Zcash support into dApps or extensions.
Document | |
---|---|
Name | dApp Code Review and Security Analysis Report for Zcash |
Audited By | Stephen Ajayi |
Approved By | Stephen Ajayi |
Website | https://webzjs.chainsafe.dev/→ |
Changelog | 07/05/2025 - Preliminary Report |
Changelog | 14/05/2025 - Remediation Report |
Changelog | 19/05/2025 - Final Report |
Platform | Metamask Snap, WASM |
Language | TypeScript, JavaScript |
Tags | Code Audit |
Methodology | https://hackenio.cc/dApp_methodology→ |
Document
- Name
- dApp Code Review and Security Analysis Report for Zcash
- Audited By
- Stephen Ajayi
- Approved By
- Stephen Ajayi
- Changelog
- 07/05/2025 - Preliminary Report
- Changelog
- 14/05/2025 - Remediation Report
- Changelog
- 19/05/2025 - Final Report
- Platform
- Metamask Snap, WASM
- Language
- TypeScript, JavaScript
- Tags
- Code Audit
- Methodology
- https://hackenio.cc/dApp_methodology→
Review Scope | |
---|---|
Repository | https://github.com/ChainSafe/WebZjs/tree/main/packages/snap→ |
Initial Commit | 6c247306e8e42dcb3d7bd0d1784e0e56e88b5d70 |
Remediation Commit | cd0901deea769231e8feee537eb66206b4ccf2e6 |
Final Commit | 477f078123a29197f3652dbe0b0e7eeb6af55002 |
Review Scope
- Initial Commit
- 6c247306e8e42dcb3d7bd0d1784e0e56e88b5d70
- Remediation Commit
- cd0901deea769231e8feee537eb66206b4ccf2e6
- Final Commit
- 477f078123a29197f3652dbe0b0e7eeb6af55002
Audit Summary
The system users should acknowledge all the risks summed up in the risks section of the report
Documentation quality
Clear Quickstart: The README concisely covers installation (
@chainsafe/webzjs-wallet
), one-time WASM/thread-pool initialization, wallet creation, account setup, and syncing—making onboarding straightforward.Key Warnings Highlighted: Important caveats (call init functions exactly once, use a gRPC-web proxy, known WASM instantiation hiccups, and un-audited status) are prominently called out.
Build & Dev Instructions: Step-by-step commands for building both the Snap and Web-Wallet, plus Docker hints for the proxy, reduce setup friction.
Areas to Improve:
Add a brief “Architecture” summary (e.g. Snap ↔ Web-Wallet ↔ gRPC-web proxy ↔ Lightwalletd) to orient new readers.
Include a short “Troubleshooting” list (common gRPC CORS errors, WASM load failures) so users can self-diagnose.
Link to a minimal example repo or CodeSandbox demonstrating end-to-end usage (wallet create → sync → sign).
Code quality
Clear RPC Handler Structure:
onRpcRequest
cleanly routes methods withsuperstruct
validation, keeping entrypoints well organized.Robust Input Validation Utilities:
validatePrivateKey
andhexStringToUint8Array
enforce strict hex format and lengths, reducing parsing errors.Centralized WASM Initialization:
initialiseWasm
wraps base64 checks and syncs into one function, preventing duplicate or faulty WASM loads.TypeScript & Typing Discipline: Well-typed
SignPcztParams
,SetBirthdayBlockParams
, and use ofPromise<...>
signatures across RPC modules improves maintainability.Safe State Management:
getSnapState
/setSnapState
usesnap_manageState
consistently, avoiding direct JSON mutation.Areas to improve
Dialog Content Sanitization & Context: Enhance
snap_dialog
dialogs to include origin/account details and escape any user-supplied text to prevent UI injection or spoofing.DRY Hex Validation in
**signPczt**
: ReplaceBuffer.from(..., 'hex')
with the existinghexStringToUint8Array
+ length check to leverage its strict checks.Manifest Least-Privilege: Remove or narrowly caveat the unused
endowment:rpc
permission so the Snap isn’t over-privileged.Consistent Error Handling: Wrap all RPC methods in try/catch with user-friendly error messages to avoid uncaught exceptions crashing the Snap.
Origin Whitelisting: Add runtime checks in
onRpcRequest
to enforceallowedOrigins
, ensuring only trusted UIs can invoke sensitive methods.
System Overview
The Snap bridges MetaMask to Zcash’s shielded ecosystem. It handles BIP-44 entropy from MetaMask, derives Unified Spending & Viewing Keys, and performs PCZT signing inside MetaMask’s secure sandbox.
Core Components:
RPC Handlers (
onRpcRequest
): Exposes methods likegetViewingKey
,signPczt
,getSeedFingerprint
, and state getters/setters.Key Management: Fetches 256-bit Zcash entropy via
snap_getBip44Entropy
, validates & converts it to a seed, and uses@chainsafe/webzjs-keys
for HD derivation.Dialog Flows: Prompts users via
snap_dialog
for every sensitive action (signing, key export, birthday-block input), leveraging MetaMask’s UI components.State Storage: Persists user settings (e.g. custom sync heights) through
snap_manageState
with safe get/update operations.WASM Initialization: Inlines and initializes
webzjs_keys_bg.wasm
viainitSync
, ensuring cryptographic routines run efficiently in the Snap’s sandbox.Integration Points:
Front-end dApp calls
ethereum.request({ method: 'wallet_invokeSnap', params: [...] })
to trigger Snap methods.MetaMask enforces permissions (dialogs, state, entropy, webassembly) as declared in
snap.manifest.json
.WebWallet handles chain synchronization separately in the browser context, not inside the Snap.
This system design ensures that all Zcash-specific cryptography and signing happen securely within MetaMask, while network sync and UI rendering occur in the unprivileged web layer.
Findings
Code ― | Title | Status | Severity | |
---|---|---|---|---|
F-2025-1014 | Over-privileged RPC Endowment | fixed | Medium | |
F-2025-1013 | Unprompted Viewing Key Exposure | fixed | Medium | |
F-2025-1013 | Unrestricted RPC Method Access | fixed | Medium | |
F-2025-1013 | Insufficient Dialog Transparency | fixed | Medium | |
F-2025-1014 | Unvalidated Custom Birthday Block Input | fixed | Low | |
F-2025-1013 | Missing Input Validation on pcztHexTring | fixed | Low | |
F-2025-1014 | Insecure Debug Logging | fixed | Observation |
Protect your dApp with insights like these.
Appendix 1. Severity Definitions
Severity | Description |
---|---|
Critical | These issues present a major security vulnerability that poses a severe risk to the system. They require immediate attention and must be resolved to prevent a potential security breach or other significant harm. |
High | These issues present a significant risk to the system, but may not require immediate attention. They should be addressed in a timely manner to reduce the risk of the potential security breach. |
Medium | These issues present a moderate risk to the system and cannot have a great impact on its function. They should be addressed in a reasonable time frame, but may not require immediate attention. |
Low | These issues present no risk to the system and typically relate to the code quality problems or general recommendations. They do not require immediate attention and should be viewed as a minor recommendation. |
Severity
- Critical
Description
- These issues present a major security vulnerability that poses a severe risk to the system. They require immediate attention and must be resolved to prevent a potential security breach or other significant harm.
Severity
- High
Description
- These issues present a significant risk to the system, but may not require immediate attention. They should be addressed in a timely manner to reduce the risk of the potential security breach.
Severity
- Medium
Description
- These issues present a moderate risk to the system and cannot have a great impact on its function. They should be addressed in a reasonable time frame, but may not require immediate attention.
Severity
- Low
Description
- These issues present no risk to the system and typically relate to the code quality problems or general recommendations. They do not require immediate attention and should be viewed as a minor recommendation.
Appendix 2. Scope
The scope of the project includes the following :
Scope Details | |
---|---|
Repository | https://github.com/ChainSafe/WebZjs/tree/main/packages/snap→ |
Initial Commit | 6c247306e8e42dcb3d7bd0d1784e0e56e88b5d70 |
Remediation Commit | cd0901deea769231e8feee537eb66206b4ccf2e6 |
Final Commit | 477f078123a29197f3652dbe0b0e7eeb6af55002 |
Scope Details
- Initial Commit
- 6c247306e8e42dcb3d7bd0d1784e0e56e88b5d70
- Remediation Commit
- cd0901deea769231e8feee537eb66206b4ccf2e6
- Final Commit
- 477f078123a29197f3652dbe0b0e7eeb6af55002