fix: security and build improvements

- Fixed biased cryptographic random with modulo operations
- Corrected biased cryptographic random with addition operations
- Resolved infinite page loading issue
- Rebuilt all distribution files
This commit is contained in:
lockbitchat
2025-10-19 23:05:24 -04:00
parent 9d0372484a
commit 49e5a054cb
4 changed files with 173 additions and 63 deletions

101
dist/app-boot.js vendored
View File

@@ -903,12 +903,15 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils {
// Generate secure password for data exchange
static generateSecurePassword() {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?";
const charCount = chars.length;
const length = 32;
const randomValues = new Uint32Array(length);
crypto.getRandomValues(randomValues);
let password = "";
for (let i = 0; i < length; i++) {
password += chars[randomValues[i] % chars.length];
let randomValue;
do {
randomValue = crypto.getRandomValues(new Uint32Array(1))[0];
} while (randomValue >= 4294967296 - 4294967296 % charCount);
password += chars[randomValue % charCount];
}
return password;
}
@@ -2591,10 +2594,14 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils {
// Generate verification code for out-of-band authentication
static generateVerificationCode() {
const chars = "0123456789ABCDEF";
const charCount = chars.length;
let result = "";
const values = crypto.getRandomValues(new Uint8Array(6));
for (let i = 0; i < 6; i++) {
result += chars[values[i] % chars.length];
let randomByte;
do {
randomByte = crypto.getRandomValues(new Uint8Array(1))[0];
} while (randomByte >= 256 - 256 % charCount);
result += chars[randomByte % charCount];
}
return result.match(/.{1,2}/g).join("-");
}
@@ -4875,12 +4882,13 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
preserveMessageSize: this._config.packetPadding.preserveMessageSize
};
this.fakeTrafficConfig = {
enabled: this._config.fakeTraffic.enabled,
minInterval: this._config.fakeTraffic.minInterval,
maxInterval: this._config.fakeTraffic.maxInterval,
minSize: this._config.fakeTraffic.minSize,
maxSize: this._config.fakeTraffic.maxSize,
patterns: this._config.fakeTraffic.patterns
enabled: this._config.fakeTraffic?.enabled || false,
minInterval: this._config.fakeTraffic?.minInterval || 15e3,
maxInterval: this._config.fakeTraffic?.maxInterval || 3e4,
minSize: this._config.fakeTraffic?.minSize || 64,
maxSize: this._config.fakeTraffic?.maxSize || 1024,
patterns: this._config.fakeTraffic?.patterns || ["heartbeat", "status", "ping"],
randomDecoyIntervals: this._config.fakeTraffic?.randomDecoyIntervals || true
};
this.fakeTrafficTimer = null;
this.lastFakeTraffic = 0;
@@ -7447,7 +7455,11 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
);
const dv = new DataView(bits);
const n = (dv.getUint32(0) ^ dv.getUint32(4)) >>> 0;
const sasCode = String(n % 1e7).padStart(7, "0");
let sasValue;
do {
sasValue = crypto.getRandomValues(new Uint32Array(1))[0];
} while (sasValue >= 4294967296 - 4294967296 % 1e7);
const sasCode = String(sasValue % 1e7).padStart(7, "0");
this._secureLog("info", "SAS code computed successfully", {
localFP: localFP.substring(0, 16) + "...",
remoteFP: remoteFP.substring(0, 16) + "...",
@@ -8121,13 +8133,36 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
this._secureLog("error", "\u274C Failed to initialize enhanced security", { errorType: error.constructor.name });
}
}
// Helper function to generate unbiased random values in a range
getUnbiasedRandomInRange(min, max) {
const range = max - min + 1;
if (range > 256) {
const bytesNeeded = Math.ceil(Math.log2(range) / 8);
const maxValue = Math.pow(256, bytesNeeded);
const threshold = maxValue - maxValue % range;
let randomValue2;
do {
const randomBytes = crypto.getRandomValues(new Uint8Array(bytesNeeded));
randomValue2 = 0;
for (let i = 0; i < bytesNeeded; i++) {
randomValue2 = (randomValue2 << 8) + randomBytes[i];
}
} while (randomValue2 >= threshold);
return randomValue2 % range + min;
}
let randomValue;
do {
randomValue = crypto.getRandomValues(new Uint8Array(1))[0];
} while (randomValue >= 256 - 256 % range);
return randomValue % range + min;
}
// Generate fingerprint mask for anti-fingerprinting with enhanced randomization
generateFingerprintMask() {
const cryptoRandom = crypto.getRandomValues(new Uint8Array(128));
const mask = {
timingOffset: cryptoRandom[0] % 1e3 + cryptoRandom[1] % 500,
timingOffset: this.getUnbiasedRandomInRange(0, 1500),
// 0-1500ms
sizeVariation: (cryptoRandom[2] % 50 + 75) / 100,
sizeVariation: this.getUnbiasedRandomInRange(75, 125) / 100,
// 0.75 to 1.25
noisePattern: Array.from(crypto.getRandomValues(new Uint8Array(64))),
// Increased size
@@ -8144,11 +8179,11 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
"X-Anonymous",
"X-Private"
],
noiseIntensity: cryptoRandom[3] % 100 + 50,
noiseIntensity: this.getUnbiasedRandomInRange(50, 150),
// 50-150%
sizeMultiplier: (cryptoRandom[4] % 50 + 75) / 100,
sizeMultiplier: this.getUnbiasedRandomInRange(75, 125) / 100,
// 0.75-1.25
timingVariation: cryptoRandom[5] % 1e3 + 100
timingVariation: this.getUnbiasedRandomInRange(100, 1100)
// 100-1100ms
};
return mask;
@@ -8478,7 +8513,10 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
try {
const fakeMessage = this.generateFakeMessage();
await this.sendFakeMessage(fakeMessage);
const nextInterval = this.fakeTrafficConfig.randomDecoyIntervals ? Math.random() * (this.fakeTrafficConfig.maxInterval - this.fakeTrafficConfig.minInterval) + this.fakeTrafficConfig.minInterval : this.fakeTrafficConfig.minInterval;
const nextInterval = this.fakeTrafficConfig.randomDecoyIntervals ? this.getUnbiasedRandomInRange(this.fakeTrafficConfig.minInterval, Math.min(this.fakeTrafficConfig.maxInterval, 6e4)) : (
// Cap at 60 seconds
this.fakeTrafficConfig.minInterval
);
const safeInterval = Math.max(nextInterval, _EnhancedSecureWebRTCManager.TIMEOUTS.FAKE_TRAFFIC_MIN_INTERVAL);
this.fakeTrafficTimer = setTimeout(sendFakeMessage, safeInterval);
} catch (error) {
@@ -8488,7 +8526,9 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
this.stopFakeTrafficGeneration();
}
};
const initialDelay = Math.random() * this.fakeTrafficConfig.maxInterval + _EnhancedSecureWebRTCManager.TIMEOUTS.DECOY_INITIAL_DELAY;
const minDelay = _EnhancedSecureWebRTCManager.TIMEOUTS.DECOY_INITIAL_DELAY;
const maxDelay = Math.min(this.fakeTrafficConfig.maxInterval, 3e4);
const initialDelay = this.getUnbiasedRandomInRange(minDelay, maxDelay);
this.fakeTrafficTimer = setTimeout(sendFakeMessage, initialDelay);
}
stopFakeTrafficGeneration() {
@@ -8498,8 +8538,9 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
}
}
generateFakeMessage() {
const pattern = this.fakeTrafficConfig.patterns[Math.floor(Math.random() * this.fakeTrafficConfig.patterns.length)];
const size = Math.floor(Math.random() * (this.fakeTrafficConfig.maxSize - this.fakeTrafficConfig.minSize + 1)) + this.fakeTrafficConfig.minSize;
const patternIndex = this.getUnbiasedRandomInRange(0, this.fakeTrafficConfig.patterns.length - 1);
const pattern = this.fakeTrafficConfig.patterns[patternIndex];
const size = this.getUnbiasedRandomInRange(this.fakeTrafficConfig.minSize, this.fakeTrafficConfig.maxSize);
const fakeData = crypto.getRandomValues(new Uint8Array(size));
return {
type: _EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE,
@@ -8961,7 +9002,7 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
}
addNoise(data) {
const dataArray = new Uint8Array(data);
const noiseSize = Math.floor(Math.random() * 32) + 8;
const noiseSize = this.getUnbiasedRandomInRange(8, 40);
const noise = crypto.getRandomValues(new Uint8Array(noiseSize));
const result = new Uint8Array(dataArray.length + noiseSize);
result.set(dataArray, 0);
@@ -8994,16 +9035,24 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
}
addRandomHeaders(data) {
const dataArray = new Uint8Array(data);
const headerCount = Math.floor(Math.random() * 3) + 1;
const headerCount = this.getUnbiasedRandomInRange(1, 3);
let totalHeaderSize = 0;
for (let i = 0; i < headerCount; i++) {
totalHeaderSize += 4 + Math.floor(Math.random() * 16) + 4;
totalHeaderSize += 4 + this.getUnbiasedRandomInRange(0, 15) + 4;
}
const result = new Uint8Array(totalHeaderSize + dataArray.length);
let offset = 0;
for (let i = 0; i < headerCount; i++) {
const headerName = this.fingerprintMask.headerVariations[Math.floor(Math.random() * this.fingerprintMask.headerVariations.length)];
const headerData = crypto.getRandomValues(new Uint8Array(Math.floor(Math.random() * 16) + 4));
let headerIndex;
do {
headerIndex = crypto.getRandomValues(new Uint8Array(1))[0];
} while (headerIndex >= 256 - 256 % this.fingerprintMask.headerVariations.length);
const headerName = this.fingerprintMask.headerVariations[headerIndex % this.fingerprintMask.headerVariations.length];
let headerSize;
do {
headerSize = crypto.getRandomValues(new Uint8Array(1))[0];
} while (headerSize >= 256 - 256 % 16);
const headerData = crypto.getRandomValues(new Uint8Array(headerSize % 16 + 4));
const headerView = new DataView(result.buffer, offset);
headerView.setUint32(0, headerData.length + 8, false);
headerView.setUint32(4, this.hashString(headerName), false);