From fd2867e5049bc829f3bc72c727ebec26327bf8e9 Mon Sep 17 00:00:00 2001 From: Miroslav Pejic Date: Fri, 16 Aug 2024 07:02:16 +0200 Subject: [PATCH] [mirotalksfu] - add new unit test and improvements --- tests/checkValidator.js | 97 ++++++++++ tests/checkXSS.js | 384 ++++++++++++++++++++-------------------- 2 files changed, 289 insertions(+), 192 deletions(-) create mode 100644 tests/checkValidator.js diff --git a/tests/checkValidator.js b/tests/checkValidator.js new file mode 100644 index 00000000..ea1050ff --- /dev/null +++ b/tests/checkValidator.js @@ -0,0 +1,97 @@ +'use strict'; + +// npx mocha checkXSS.js + +require('should'); + +const checkXSS = require('../app/src/Validator'); + +describe('checkValidator', () => { + describe('1. Handling valid room name', () => { + it('should return false for non-string inputs', () => { + checkXSS.isValidRoomName(123).should.be.false(); + checkXSS.isValidRoomName({}).should.be.false(); + checkXSS.isValidRoomName([]).should.be.false(); + checkXSS.isValidRoomName(null).should.be.false(); + checkXSS.isValidRoomName(undefined).should.be.false(); + }); + + it('should return true for valid room name', () => { + checkXSS.isValidRoomName('Room1').should.be.true(); + checkXSS.isValidRoomName('ConferenceRoom').should.be.true(); + checkXSS.isValidRoomName('Room_123').should.be.true(); + checkXSS.isValidRoomName('30521HungryHat').should.be.true(); + checkXSS.isValidRoomName('dbc4a9d9-6879-479a-b8fe-cedaad176b0d').should.be.true(); + }); + + it('should return false for room name with path traversal', () => { + checkXSS.isValidRoomName('../etc/passwd').should.be.false(); + checkXSS.isValidRoomName('..\\etc\\passwd').should.be.false(); + checkXSS.isValidRoomName('Room/../../etc').should.be.false(); + checkXSS.isValidRoomName('Room\\..\\..\\etc').should.be.false(); + }); + + it('should return true for room names with special characters that do not imply path traversal', () => { + checkXSS.isValidRoomName('Room_@!#$%^&*()').should.be.true(); + checkXSS.isValidRoomName('Room-Name').should.be.true(); + checkXSS.isValidRoomName('Room.Name').should.be.true(); + }); + }); + + describe('2. Handling valid recording file name', () => { + it('should return false for non-string inputs', () => { + checkXSS.isValidRecFileNameFormat(123).should.be.false(); + checkXSS.isValidRecFileNameFormat({}).should.be.false(); + checkXSS.isValidRecFileNameFormat([]).should.be.false(); + checkXSS.isValidRecFileNameFormat(null).should.be.false(); + checkXSS.isValidRecFileNameFormat(undefined).should.be.false(); + }); + + it('should return false for strings that do not start with "Rec_" or end with ".webm"', () => { + checkXSS.isValidRecFileNameFormat('Recording.webm').should.be.false(); + checkXSS.isValidRecFileNameFormat('Rec_Recording.mp4').should.be.false(); + checkXSS.isValidRecFileNameFormat('rec_Recording.webm').should.be.false(); + checkXSS.isValidRecFileNameFormat('RecordingRec_.webm').should.be.false(); + }); + + it('should return true for valid recording file name format', () => { + checkXSS.isValidRecFileNameFormat('Rec_Meeting1.webm').should.be.true(); + checkXSS.isValidRecFileNameFormat('Rec_Session_2024.webm').should.be.true(); + checkXSS.isValidRecFileNameFormat('Rec_Test.webm').should.be.true(); + }); + + it('should return false for recording file name format with path traversal', () => { + checkXSS.isValidRecFileNameFormat('../Rec_Test.webm').should.be.false(); + checkXSS.isValidRecFileNameFormat('Rec_../Test.webm').should.be.false(); + checkXSS.isValidRecFileNameFormat('Rec_Test/../../config.webm').should.be.false(); + checkXSS.isValidRecFileNameFormat('Rec_Test\\..\\..\\config.webm').should.be.false(); + }); + }); + + describe('3. Handle path traversal', () => { + it('should return false for strings without path traversal', () => { + checkXSS.hasPathTraversal('Room1').should.be.false(); + checkXSS.hasPathTraversal('Rec_Test.webm').should.be.false(); + checkXSS.hasPathTraversal('simple/path').should.be.false(); + }); + + it('should return true for strings with path traversal', () => { + checkXSS.hasPathTraversal('../etc/passwd').should.be.true(); + checkXSS.hasPathTraversal('..\\etc\\passwd').should.be.true(); + checkXSS.hasPathTraversal('Room/../../etc').should.be.true(); + checkXSS.hasPathTraversal('Room\\..\\..\\etc').should.be.true(); + }); + + it('should return false for strings with ".." that do not indicate path traversal', () => { + checkXSS.hasPathTraversal('Room..').should.be.false(); + checkXSS.hasPathTraversal('Rec..webm').should.be.false(); + checkXSS.hasPathTraversal('NoPathTraversalHere..').should.be.false(); + }); + + it('should return true for complex path traversal patterns', () => { + checkXSS.hasPathTraversal('....//').should.be.true(); + checkXSS.hasPathTraversal('..\\..\\').should.be.true(); + checkXSS.hasPathTraversal('.../../').should.be.true(); + }); + }); +}); diff --git a/tests/checkXSS.js b/tests/checkXSS.js index 373c60db..765c7fe7 100644 --- a/tests/checkXSS.js +++ b/tests/checkXSS.js @@ -1,218 +1,218 @@ 'use strict'; -// npx mocha test-checkXSS.js +// npx mocha checkXSS.js require('should'); const checkXSS = require('../app/src/XSS'); describe('checkXSS', () => { - // 1. Basic Data Types Handling + describe('1. Basic Data Types Handling', () => { + it('should return numbers and booleans unchanged', () => { + checkXSS(42).should.equal(42); + checkXSS(true).should.equal(true); + }); - it('should return numbers and booleans unchanged', () => { - checkXSS(42).should.equal(42); - checkXSS(true).should.equal(true); + it('should return null and undefined unchanged', () => { + should.not.exist(checkXSS(null)); + should.not.exist(checkXSS(undefined)); + }); }); - it('should return null and undefined unchanged', () => { - should.not.exist(checkXSS(null)); - should.not.exist(checkXSS(undefined)); + describe('2. Simple String Handling', () => { + it('should sanitize strings with XSS injections', () => { + const maliciousString = ''; + const sanitizedString = checkXSS(maliciousString); + sanitizedString.should.not.containEql(''); + }); + + it('should sanitize complex XSS injections', () => { + const complexString = ''; + const sanitizedString = checkXSS(complexString); + sanitizedString.should.not.containEql('onload'); + sanitizedString.should.equal(''); + }); + + it('should sanitize HTML attributes', () => { + const maliciousHtml = 'click me'; + const sanitizedHtml = checkXSS(maliciousHtml); + sanitizedHtml.should.not.containEql('javascript:'); + sanitizedHtml.should.containEql('click me'); + }); + + it('should sanitize embedded scripts in HTML', () => { + const maliciousHtml = '
'; + const sanitizedHtml = checkXSS(maliciousHtml); + sanitizedHtml.should.not.containEql('', + key2: 'normal string', + }; + const sanitizedObject = checkXSS(maliciousObject); + sanitizedObject.key1.should.not.containEql(''); + sanitizedObject.key2.should.equal('normal string'); + }); - it('should sanitize strings with XSS injections', () => { - const maliciousString = ''; - const sanitizedString = checkXSS(maliciousString); - sanitizedString.should.not.containEql(''); + it('should sanitize arrays with XSS injections', () => { + const maliciousArray = ['', 'normal string']; + const sanitizedArray = checkXSS(maliciousArray); + sanitizedArray[0].should.not.containEql(''); + sanitizedArray[1].should.equal('normal string'); + }); + + it('should handle nested objects and arrays with XSS injections', () => { + const nestedData = { + key1: [ + '', + { + key2: '', + }, + ], + }; + const sanitizedData = checkXSS(nestedData); + sanitizedData.key1[0].should.not.containEql(''); + sanitizedData.key1[1].key2.should.not.containEql('onerror'); + sanitizedData.key1[1].key2.should.equal(''); + }); + + it('should handle XSS in nested HTML elements', () => { + const nestedXss = '
Click me
'; + const sanitizedNestedXss = checkXSS(nestedXss); + sanitizedNestedXss.should.not.containEql('onclick'); + sanitizedNestedXss.should.containEql('
Click me
'); + }); + + it('should handle XSS through malicious attributes in different tags', () => { + const maliciousAttributes = + 'Link'; + const sanitizedAttributes = checkXSS(maliciousAttributes); + sanitizedAttributes.should.not.containEql('onclick'); + sanitizedAttributes.should.not.containEql('javascript:'); + sanitizedAttributes.should.not.containEql('alert'); + }); }); - it('should sanitize complex XSS injections', () => { - const complexString = ''; - const sanitizedString = checkXSS(complexString); - sanitizedString.should.not.containEql('onload'); - sanitizedString.should.equal(''); + describe('4. Handling Specific Formats (JSON, Base64, etc.)', () => { + it('should handle XSS in JSON data', () => { + const maliciousJson = '{"key": ""}'; + const sanitizedJson = checkXSS(JSON.parse(maliciousJson)); + sanitizedJson.key.should.not.containEql('onerror'); + sanitizedJson.key.should.equal(''); + }); + + it('should sanitize base64 encoded content', () => { + const maliciousBase64 = ''; + const sanitizedBase64 = checkXSS(maliciousBase64); + sanitizedBase64.should.not.containEql('onload'); + sanitizedBase64.should.equal(''); + }); + + it('should sanitize encoded HTML entities', () => { + const encodedHtmlEntities = '<script>alert('xss')</script>'; + const sanitizedEntities = checkXSS(encodedHtmlEntities); + sanitizedEntities.should.not.containEql(''; - const sanitizedHtml = checkXSS(maliciousHtml); - sanitizedHtml.should.not.containEql(''; + const sanitizedSvgXss = checkXSS(svgXss); + sanitizedSvgXss.should.not.containEql(''; + const sanitizedDynamicXss = checkXSS(dynamicXss); + sanitizedDynamicXss.should.not.containEql('onerror'); + sanitizedDynamicXss.should.containEql('
'); + }); }); - it('should handle special characters used in XSS attacks', () => { - const specialCharsXss = "
\">Test
"; - const sanitizedSpecialChars = checkXSS(specialCharsXss); - sanitizedSpecialChars.should.not.containEql('onerror'); - sanitizedSpecialChars.should.containEql('
Test
'); - }); - - // 3. Handling Objects, Arrays, and Nested Structures - - it('should sanitize objects with XSS injections', () => { - const maliciousObject = { - key1: '', - key2: 'normal string', - }; - const sanitizedObject = checkXSS(maliciousObject); - sanitizedObject.key1.should.not.containEql(''); - sanitizedObject.key2.should.equal('normal string'); - }); - - it('should sanitize arrays with XSS injections', () => { - const maliciousArray = ['', 'normal string']; - const sanitizedArray = checkXSS(maliciousArray); - sanitizedArray[0].should.not.containEql(''); - sanitizedArray[1].should.equal('normal string'); - }); - - it('should handle nested objects and arrays with XSS injections', () => { - const nestedData = { - key1: [ - '', - { - key2: '', - }, - ], - }; - const sanitizedData = checkXSS(nestedData); - sanitizedData.key1[0].should.not.containEql(''); - sanitizedData.key1[1].key2.should.not.containEql('onerror'); - sanitizedData.key1[1].key2.should.equal(''); - }); - - it('should handle XSS in nested HTML elements', () => { - const nestedXss = '
Click me
'; - const sanitizedNestedXss = checkXSS(nestedXss); - sanitizedNestedXss.should.not.containEql('onclick'); - sanitizedNestedXss.should.containEql('
Click me
'); - }); - - it('should handle XSS through malicious attributes in different tags', () => { - const maliciousAttributes = - 'Link'; - const sanitizedAttributes = checkXSS(maliciousAttributes); - sanitizedAttributes.should.not.containEql('onclick'); - sanitizedAttributes.should.not.containEql('javascript:'); - sanitizedAttributes.should.not.containEql('alert'); - }); - - // 4. Handling Specific Formats (JSON, Base64, etc.) - - it('should handle XSS in JSON data', () => { - const maliciousJson = '{"key": ""}'; - const sanitizedJson = checkXSS(JSON.parse(maliciousJson)); - sanitizedJson.key.should.not.containEql('onerror'); - sanitizedJson.key.should.equal(''); - }); - - it('should sanitize base64 encoded content', () => { - const maliciousBase64 = ''; - const sanitizedBase64 = checkXSS(maliciousBase64); - sanitizedBase64.should.not.containEql('onload'); - sanitizedBase64.should.equal(''); - }); - - it('should sanitize encoded HTML entities', () => { - const encodedHtmlEntities = '<script>alert('xss')</script>'; - const sanitizedEntities = checkXSS(encodedHtmlEntities); - sanitizedEntities.should.not.containEql(''; - const sanitizedSvgXss = checkXSS(svgXss); - sanitizedSvgXss.should.not.containEql(''; - const sanitizedDynamicXss = checkXSS(dynamicXss); - sanitizedDynamicXss.should.not.containEql('onerror'); - sanitizedDynamicXss.should.containEql('
'); - }); - - // 8. Handling Mixed Content - - it('should sanitize mixed content', () => { - const mixedContent = '
Normal text more text
'; - const sanitizedContent = checkXSS(mixedContent); - sanitizedContent.should.not.containEql(' more text'; + const sanitizedContent = checkXSS(mixedContent); + sanitizedContent.should.not.containEql('