release: v4.8.13 message integrity & transport hardening
Bumps version to 4.8.13 across package.json, package-lock.json, manifest.json, index.html, meta.json, README, SECURITY_DISCLAIMER, the site header and the in-app init banner (previously desynced at 4.8.10/4.8.11/4.8.12). Ships the security-review fixes already on main: - removed the over-broad send-path keyword blocklist that silently rejected legitimate messages (real XSS defense remains receive-side DOMPurify) - preserve newlines/tabs/indentation in outgoing message sanitization - stop logging raw AAD (sessionId + keyFingerprint) on validation failure - add Strict-Transport-Security and Permissions-Policy headers - add outgoing-message-integrity regression tests
This commit is contained in:
@@ -1,5 +1,24 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v4.8.13 — Message integrity & transport hardening
|
||||||
|
|
||||||
|
Security review follow-up. The end-to-end cryptography (ECDH, AES-GCM, PBKDF2, SAS bound to DTLS fingerprints, anti-replay) was verified sound; these changes fix availability/integrity defects on the send path and tighten transport headers and logging.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Outgoing messages were silently rejected by an over-broad keyword blocklist in `_validateInputData`. Plain words such as "constructor", "global", "document.", "prototype", or the literal text "javascript:" caused `sendSecureMessage` to throw, so legitimate messages never reached the peer. The blocklist provided no real protection: XSS is enforced at the rendering boundary by the receive-side DOMPurify pass and by `sanitizeMessage()` before encryption. The send-path blocklist was removed.
|
||||||
|
- `_sanitizeInputString` collapsed all whitespace (`/\s+/g` to a single space), destroying multi-line messages and code snippets (`"a\nb\nc"` became `"a b c"`). Newlines, tabs and indentation are now preserved; only control characters are stripped and runs of 3+ blank lines are collapsed to two.
|
||||||
|
- AAD validation failures logged the raw AAD string, which carried `sessionId` and `keyFingerprint`. Both the message and file-message validators now log only the AAD length.
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Added `Strict-Transport-Security` (`max-age=63072000; includeSubDomains; preload`) to `deploy/nginx.conf` and `.htaccess`, closing the first-visit SSL-strip window that `upgrade-insecure-requests` alone does not cover.
|
||||||
|
- Added a restrictive `Permissions-Policy` (`camera=(self)` for in-page QR scanning; microphone, geolocation, payment, usb and sensors denied).
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
- Added `tests/outgoing-message-integrity.test.mjs` covering keyword acceptance, multi-line/indentation preservation, control-character stripping, blank-line collapsing, and the size limit.
|
||||||
|
|
||||||
## v4.8.12 — Chat notification & file-transfer UI fixes
|
## v4.8.12 — Chat notification & file-transfer UI fixes
|
||||||
|
|
||||||
Fixes duplicated chat output and a layout overflow in the message list.
|
Fixes duplicated chat output and a layout overflow in the message list.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# SecureBit.chat v4.8.11
|
# SecureBit.chat v4.8.13
|
||||||
|
|
||||||
SecureBit.chat is a browser-based peer-to-peer chat application built on WebRTC and Web Crypto APIs. It is designed for direct encrypted communication, explicit peer verification, and a small operational footprint without account registration or server-side message storage.
|
SecureBit.chat is a browser-based peer-to-peer chat application built on WebRTC and Web Crypto APIs. It is designed for direct encrypted communication, explicit peer verification, and a small operational footprint without account registration or server-side message storage.
|
||||||
|
|
||||||
@@ -15,7 +15,14 @@ SecureBit.chat uses:
|
|||||||
|
|
||||||
A session is not treated as verified until both peers complete the interactive SAS flow. Each user must compare the displayed code with the peer through an out-of-band channel and enter the matching code manually. Three failed SAS attempts terminate the session.
|
A session is not treated as verified until both peers complete the interactive SAS flow. Each user must compare the displayed code with the peer through an out-of-band channel and enter the matching code manually. Three failed SAS attempts terminate the session.
|
||||||
|
|
||||||
## Highlights in v4.8.11
|
## Highlights in v4.8.13
|
||||||
|
|
||||||
|
- Security/integrity: outgoing chat messages are no longer silently rejected by an over-broad keyword blocklist (plain words like "constructor", "global", "document." or the literal text "javascript:" were being blocked). XSS is still prevented at the rendering boundary by the receive-side DOMPurify pass and by message sanitization before encryption.
|
||||||
|
- Integrity: multi-line messages and code snippets keep their newlines and indentation instead of being collapsed onto a single line.
|
||||||
|
- Privacy: AAD validation failures no longer log the raw AAD (which carried `sessionId` and `keyFingerprint`); only its length is logged.
|
||||||
|
- Hardening: production now sends `Strict-Transport-Security` (2-year, preload) and a restrictive `Permissions-Policy` (camera kept for in-page QR scanning; microphone, geolocation and sensors denied).
|
||||||
|
|
||||||
|
Earlier in v4.8.11:
|
||||||
|
|
||||||
- Fixed: file transfers that completed the consent handshake but never delivered any data. Chunks are now sized to stay under WebRTC's 64 KB SCTP message limit (most visible on Safari and cross-browser connections).
|
- Fixed: file transfers that completed the consent handshake but never delivered any data. Chunks are now sized to stay under WebRTC's 64 KB SCTP message limit (most visible on Safari and cross-browser connections).
|
||||||
- File-type validation is now extension-driven; the easily-spoofed MIME type is advisory, so files with a missing or cross-OS MIME variant are no longer wrongly rejected. Blocked executable/script extensions and size limits are still enforced.
|
- File-type validation is now extension-driven; the easily-spoofed MIME type is advisory, so files with a missing or cross-OS MIME variant are no longer wrongly rejected. Blocked executable/script extensions and size limits are still enforced.
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ SecureBit.chat is intended for legitimate private communication, journalism, res
|
|||||||
|
|
||||||
## Current release
|
## Current release
|
||||||
|
|
||||||
- Product release: `v4.8.10`
|
- Product release: `v4.8.13`
|
||||||
- Protocol version: `4.1`
|
- Protocol version: `4.1`
|
||||||
- Last updated: May 17, 2026
|
- Last updated: May 17, 2026
|
||||||
|
|||||||
Vendored
+1
-1
@@ -17435,7 +17435,7 @@ Right-click or Ctrl+click to disconnect`,
|
|||||||
React.createElement("p", {
|
React.createElement("p", {
|
||||||
key: "subtitle",
|
key: "subtitle",
|
||||||
className: "text-xs sm:text-sm text-muted hidden sm:block"
|
className: "text-xs sm:text-sm text-muted hidden sm:block"
|
||||||
}, "End-to-end freedom v4.8.12")
|
}, "End-to-end freedom v4.8.13")
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
// Status and Controls - Responsive
|
// Status and Controls - Responsive
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1987,7 +1987,7 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleMessage(" SecureBit.chat Enhanced Security Edition v4.8.12 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.", "system");
|
handleMessage(" SecureBit.chat Enhanced Security Edition v4.8.13 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.", "system");
|
||||||
const handleBeforeUnload = (event) => {
|
const handleBeforeUnload = (event) => {
|
||||||
if (event.type === "beforeunload" && !isTabSwitching) {
|
if (event.type === "beforeunload" && !isTabSwitching) {
|
||||||
if (webrtcManagerRef.current && webrtcManagerRef.current.isConnected()) {
|
if (webrtcManagerRef.current && webrtcManagerRef.current.isConnected()) {
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+5
-5
@@ -113,7 +113,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- GitHub Pages SEO -->
|
<!-- GitHub Pages SEO -->
|
||||||
<meta name="description" content="SecureBit.chat v4.8.12 — P2P messenger with ECDH + DTLS + SAS security and 18-layer military-grade cryptography">
|
<meta name="description" content="SecureBit.chat v4.8.13 — P2P messenger with ECDH + DTLS + SAS security and 18-layer military-grade cryptography">
|
||||||
<meta name="keywords" content="P2P messenger, ECDH, DTLS, SAS, encryption, WebRTC, privacy, ASN.1 validation, military-grade security, 18-layer defense, MITM protection, PFS">
|
<meta name="keywords" content="P2P messenger, ECDH, DTLS, SAS, encryption, WebRTC, privacy, ASN.1 validation, military-grade security, 18-layer defense, MITM protection, PFS">
|
||||||
<meta name="author" content="Volodymyr">
|
<meta name="author" content="Volodymyr">
|
||||||
<link rel="canonical" href="https://github.com/SecureBitChat/securebit-chat/">
|
<link rel="canonical" href="https://github.com/SecureBitChat/securebit-chat/">
|
||||||
@@ -148,13 +148,13 @@
|
|||||||
<!-- Update Manager - система принудительного обновления -->
|
<!-- Update Manager - система принудительного обновления -->
|
||||||
<script src="src/utils/updateManager.js"></script>
|
<script src="src/utils/updateManager.js"></script>
|
||||||
<script type="module" src="src/components/UpdateChecker.jsx"></script>
|
<script type="module" src="src/components/UpdateChecker.jsx"></script>
|
||||||
<script type="module" src="dist/qr-local.js?v=1781732923420"></script>
|
<script type="module" src="dist/qr-local.js?v=1781816839471"></script>
|
||||||
<script type="module" src="src/components/QRScanner.js?v=1781732923420"></script>
|
<script type="module" src="src/components/QRScanner.js?v=1781816839471"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="dist/app-boot.js?v=1781732923420"></script>
|
<script type="module" src="dist/app-boot.js?v=1781816839471"></script>
|
||||||
<script type="module" src="dist/app.js?v=1781732923420"></script>
|
<script type="module" src="dist/app.js?v=1781816839471"></script>
|
||||||
|
|
||||||
<script src="src/scripts/pwa-register.js"></script>
|
<script src="src/scripts/pwa-register.js"></script>
|
||||||
<script src="./src/pwa/install-prompt.js" type="module"></script>
|
<script src="./src/pwa/install-prompt.js" type="module"></script>
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "SecureBit.chat v4.8.12 - ECDH + DTLS + SAS",
|
"name": "SecureBit.chat v4.8.13 - ECDH + DTLS + SAS",
|
||||||
"short_name": "SecureBit",
|
"short_name": "SecureBit",
|
||||||
"description": "P2P messenger with ECDH + DTLS + SAS security, military-grade cryptography and Lightning Network payments",
|
"description": "P2P messenger with ECDH + DTLS + SAS security, military-grade cryptography and Lightning Network payments",
|
||||||
"start_url": "./",
|
"start_url": "./",
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"version": "1781732923420",
|
"version": "1781816839471",
|
||||||
"buildVersion": "1781732923420",
|
"buildVersion": "1781816839471",
|
||||||
"appVersion": "4.8.12",
|
"appVersion": "4.8.13",
|
||||||
"buildTime": "2026-06-17T21:48:43.476Z",
|
"buildTime": "2026-06-18T21:07:19.513Z",
|
||||||
"buildId": "1781732923420-be1d02f",
|
"buildId": "1781816839471-42be55a",
|
||||||
"gitHash": "be1d02f",
|
"gitHash": "42be55a",
|
||||||
"generated": true,
|
"generated": true,
|
||||||
"generatedAt": "2026-06-17T21:48:43.478Z"
|
"generatedAt": "2026-06-18T21:07:19.514Z"
|
||||||
}
|
}
|
||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "securebit-chat",
|
"name": "securebit-chat",
|
||||||
"version": "4.8.10",
|
"version": "4.8.13",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "securebit-chat",
|
"name": "securebit-chat",
|
||||||
"version": "4.8.10",
|
"version": "4.8.13",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base64-js": "1.5.1",
|
"base64-js": "1.5.1",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "securebit-chat",
|
"name": "securebit-chat",
|
||||||
"version": "4.8.12",
|
"version": "4.8.13",
|
||||||
"description": "Secure P2P Communication Application with End-to-End Encryption",
|
"description": "Secure P2P Communication Application with End-to-End Encryption",
|
||||||
"main": "index.html",
|
"main": "index.html",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+1
-1
@@ -2071,7 +2071,7 @@ import { loadIceSettings, saveIceSettings, clearIceSettings } from './network/ic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMessage(' SecureBit.chat Enhanced Security Edition v4.8.12 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.', 'system');
|
handleMessage(' SecureBit.chat Enhanced Security Edition v4.8.13 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.', 'system');
|
||||||
|
|
||||||
const handleBeforeUnload = (event) => {
|
const handleBeforeUnload = (event) => {
|
||||||
if (event.type === 'beforeunload' && !isTabSwitching) {
|
if (event.type === 'beforeunload' && !isTabSwitching) {
|
||||||
|
|||||||
@@ -539,7 +539,7 @@ const EnhancedMinimalHeader = ({
|
|||||||
React.createElement('p', {
|
React.createElement('p', {
|
||||||
key: 'subtitle',
|
key: 'subtitle',
|
||||||
className: 'text-xs sm:text-sm text-muted hidden sm:block'
|
className: 'text-xs sm:text-sm text-muted hidden sm:block'
|
||||||
}, 'End-to-end freedom v4.8.12')
|
}, 'End-to-end freedom v4.8.13')
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user