fix: harden chat sanitization with DOMPurify
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { JSDOM } from 'jsdom';
|
||||
|
||||
globalThis.window = {
|
||||
DEBUG_MODE: true,
|
||||
DEVELOPMENT_MODE: true,
|
||||
webpackHotUpdate: {},
|
||||
location: {
|
||||
hostname: 'localhost',
|
||||
search: '?debug'
|
||||
}
|
||||
};
|
||||
const { window } = new JSDOM('<!doctype html><html><body></body></html>', {
|
||||
url: 'http://localhost/?debug'
|
||||
});
|
||||
window.DEBUG_MODE = true;
|
||||
window.DEVELOPMENT_MODE = true;
|
||||
window.webpackHotUpdate = {};
|
||||
globalThis.window = window;
|
||||
|
||||
const { EnhancedSecureCryptoUtils } = await import('../src/crypto/EnhancedSecureCryptoUtils.js');
|
||||
window.EnhancedSecureCryptoUtils = EnhancedSecureCryptoUtils;
|
||||
@@ -33,18 +32,38 @@ function createManager() {
|
||||
assert.deepEqual(manager.delivered[0], { message: 'hello secure world', type: 'received' });
|
||||
}
|
||||
|
||||
// XSS-like and HTML payloads are sanitized before UI delivery.
|
||||
// Script payloads are removed while harmless visible text survives.
|
||||
{
|
||||
const manager = createManager();
|
||||
EnhancedSecureWebRTCManager.prototype.deliverMessageToUI.call(manager, '<script>alert(1)</script>Hello <b>peer</b>', 'received');
|
||||
assert.deepEqual(manager.delivered[0], { message: 'Hello peer', type: 'received' });
|
||||
}
|
||||
|
||||
// Event-handler and protocol strings are removed before reaching React state.
|
||||
// Dangerous protocols in markup and event handlers never reach React state.
|
||||
{
|
||||
const manager = createManager();
|
||||
EnhancedSecureWebRTCManager.prototype.deliverMessageToUI.call(manager, '<img src=x onerror=alert(1)> javascript:alert(1)', 'received');
|
||||
assert.deepEqual(manager.delivered[0], { message: 'alert(1)', type: 'received' });
|
||||
EnhancedSecureWebRTCManager.prototype.deliverMessageToUI.call(manager, '<a href="javascript:alert(1)">click</a><details ontoggle="alert(1)">open</details>', 'received');
|
||||
assert.deepEqual(manager.delivered[0], { message: 'clickopen', type: 'received' });
|
||||
}
|
||||
|
||||
// SVG payloads and malformed HTML do not create executable remnants.
|
||||
{
|
||||
const manager = createManager();
|
||||
EnhancedSecureWebRTCManager.prototype.deliverMessageToUI.call(manager, '<svg><script>alert(1)</script><a xlink:href="javascript:alert(2)">x</a></svg>', 'received');
|
||||
assert.deepEqual(manager.delivered[0], { message: '', type: 'received' });
|
||||
|
||||
const malformedManager = createManager();
|
||||
EnhancedSecureWebRTCManager.prototype.deliverMessageToUI.call(malformedManager, '<div><b>Hello<script>alert(1)', 'received');
|
||||
assert.deepEqual(malformedManager.delivered[0], { message: 'Hello', type: 'received' });
|
||||
}
|
||||
|
||||
// Plain text and Unicode text stay plain and intact.
|
||||
{
|
||||
const manager = createManager();
|
||||
EnhancedSecureWebRTCManager.prototype.deliverMessageToUI.call(manager, 'javascript: is harmless as plain text', 'received');
|
||||
EnhancedSecureWebRTCManager.prototype.deliverMessageToUI.call(manager, 'Привет 👋 こんにちは', 'received');
|
||||
assert.deepEqual(manager.delivered[0], { message: 'javascript: is harmless as plain text', type: 'received' });
|
||||
assert.deepEqual(manager.delivered[1], { message: 'Привет 👋 こんにちは', type: 'received' });
|
||||
}
|
||||
|
||||
// Outgoing/system messages are not altered by the incoming-message gate.
|
||||
|
||||
Reference in New Issue
Block a user