diff --git a/Build/Sources/TypeScript/core/Resources/Public/TypeScript/SecurityUtility.ts b/Build/Sources/TypeScript/core/Resources/Public/TypeScript/SecurityUtility.ts index 5916f2e257c454414615323ea93355c68c321140..fc709ddd26c56c6ed1b27c9cc4106f7ac007c09e 100644 --- a/Build/Sources/TypeScript/core/Resources/Public/TypeScript/SecurityUtility.ts +++ b/Build/Sources/TypeScript/core/Resources/Public/TypeScript/SecurityUtility.ts @@ -59,7 +59,9 @@ class SecurityUtility { // apply arbitrary data a text node // thus browser is capable of properly encoding anvil.innerText = value; - return anvil.innerHTML; + return anvil.innerHTML + .replace(/"/g, '"') + .replace(/'/g, '''); } /** diff --git a/Build/Sources/TypeScript/core/Tests/SecurityUtilityTest.ts b/Build/Sources/TypeScript/core/Tests/SecurityUtilityTest.ts index ca3306386ee0b0b548524834f5dae1141685d442..512cb8b9c428a8c5cd81df1df09413117453a3a6 100644 --- a/Build/Sources/TypeScript/core/Tests/SecurityUtilityTest.ts +++ b/Build/Sources/TypeScript/core/Tests/SecurityUtilityTest.ts @@ -36,4 +36,8 @@ describe('TYPO3/CMS/Core/SecurityUtility', (): void => { expect(() => (new SecurityUtility()).getRandomHexValue(invalidLength)).toThrowError(SyntaxError); } }); + + it('encodes HTML', (): void => { + expect((new SecurityUtility).encodeHtml('<>"\'&')).toBe('<>"'&'); + }); }); diff --git a/typo3/sysext/core/Resources/Public/JavaScript/SecurityUtility.js b/typo3/sysext/core/Resources/Public/JavaScript/SecurityUtility.js index 0ccc45986cde7286e4d481cad435d4fb21bd8c76..880a3740a6e78e3211cdc3fe98b487874a2103b0 100644 --- a/typo3/sysext/core/Resources/Public/JavaScript/SecurityUtility.js +++ b/typo3/sysext/core/Resources/Public/JavaScript/SecurityUtility.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -define(["require","exports"],(function(e,t){"use strict";return class{constructor(e=document){this.documentRef=e}getRandomHexValue(e){if(e<=0||e!==Math.ceil(e))throw new SyntaxError("Length must be a positive integer");const t=new Uint8Array(Math.ceil(e/2));return crypto.getRandomValues(t),Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("").substr(0,e)}encodeHtml(e,t=!0){let n=this.createAnvil();return t||(e=e.replace(/&[#A-Za-z0-9]+;/g,e=>(n.innerHTML=e,n.innerText))),n.innerText=e,n.innerHTML}debug(e){e!==this.encodeHtml(e)&&console.warn("XSS?!",e)}createAnvil(){return this.documentRef.createElement("span")}}})); \ No newline at end of file +define(["require","exports"],(function(e,t){"use strict";return class{constructor(e=document){this.documentRef=e}getRandomHexValue(e){if(e<=0||e!==Math.ceil(e))throw new SyntaxError("Length must be a positive integer");const t=new Uint8Array(Math.ceil(e/2));return crypto.getRandomValues(t),Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("").substr(0,e)}encodeHtml(e,t=!0){let r=this.createAnvil();return t||(e=e.replace(/&[#A-Za-z0-9]+;/g,e=>(r.innerHTML=e,r.innerText))),r.innerText=e,r.innerHTML.replace(/"/g,""").replace(/'/g,"'")}debug(e){e!==this.encodeHtml(e)&&console.warn("XSS?!",e)}createAnvil(){return this.documentRef.createElement("span")}}})); \ No newline at end of file diff --git a/typo3/sysext/core/Tests/JavaScript/SecurityUtilityTest.js b/typo3/sysext/core/Tests/JavaScript/SecurityUtilityTest.js index bc11df0088741183ca79b86585f19ea824bcb49b..bdd00fdcbf61767b97900305abd56808d5848a9b 100644 --- a/typo3/sysext/core/Tests/JavaScript/SecurityUtilityTest.js +++ b/typo3/sysext/core/Tests/JavaScript/SecurityUtilityTest.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -define(["require","exports","TYPO3/CMS/Core/SecurityUtility"],(function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),describe("TYPO3/CMS/Core/SecurityUtility",()=>{it("generates random hex value",()=>{for(let e of function*(){yield 1,yield 20,yield 39}()){const t=(new r).getRandomHexValue(e);expect(t.length).toBe(e)}}),it("throws SyntaxError on invalid length",()=>{for(let e of function*(){yield 0,yield-90,yield 10.3}())expect(()=>(new r).getRandomHexValue(e)).toThrowError(SyntaxError)})})})); \ No newline at end of file +define(["require","exports","TYPO3/CMS/Core/SecurityUtility"],(function(e,t,o){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),describe("TYPO3/CMS/Core/SecurityUtility",()=>{it("generates random hex value",()=>{for(let e of function*(){yield 1,yield 20,yield 39}()){const t=(new o).getRandomHexValue(e);expect(t.length).toBe(e)}}),it("throws SyntaxError on invalid length",()=>{for(let e of function*(){yield 0,yield-90,yield 10.3}())expect(()=>(new o).getRandomHexValue(e)).toThrowError(SyntaxError)}),it("encodes HTML",()=>{expect((new o).encodeHtml("<>\"'&")).toBe("<>"'&")})})})); \ No newline at end of file