From 368d47cb8974dcaedef44aad6d8e5c7f2d202a61 Mon Sep 17 00:00:00 2001 From: Hristo Terezov Date: Thu, 29 Jun 2023 13:46:37 -0500 Subject: [PATCH] fix(chat-URLs): Use punycode only on host name. This is workaround for PunycodeJS which truncates parts of the URL when it contains '@'. --- package-lock.json | 14 ++++----- package.json | 2 +- .../base/react/components/web/Linkify.tsx | 31 ++++++++++++++++++- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index a2610e38bdd31..be1d648b7e999 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,7 +67,7 @@ "null-loader": "4.0.1", "optional-require": "1.0.3", "promise.allsettled": "1.0.4", - "punycode": "2.1.1", + "punycode": "2.3.0", "react": "18.2.0", "react-dom": "18.2.0", "react-emoji-render": "1.2.4", @@ -15403,9 +15403,9 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "engines": { "node": ">=6" } @@ -31286,9 +31286,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" }, "qs": { "version": "6.9.7", diff --git a/package.json b/package.json index 0dbcc9dac2503..597e436cfa881 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "null-loader": "4.0.1", "optional-require": "1.0.3", "promise.allsettled": "1.0.4", - "punycode": "2.1.1", + "punycode": "2.3.0", "react": "18.2.0", "react-dom": "18.2.0", "react-emoji-render": "1.2.4", diff --git a/react/features/base/react/components/web/Linkify.tsx b/react/features/base/react/components/web/Linkify.tsx index 3090e0ed918ae..b442e99db4d6a 100644 --- a/react/features/base/react/components/web/Linkify.tsx +++ b/react/features/base/react/components/web/Linkify.tsx @@ -37,13 +37,42 @@ export default class Linkify extends Component { * @returns {React$Node} */ _componentDecorator(decoratedHref: string, decoratedText: string, key: number) { + let text; + + // In order to prevent homograph attacks we need to use punycode. Reference + // https://github.com/tasti/react-linkify/issues/84. In the same time it seems PunycodeJS will treat the URL + // as an email when there is '@' and will erase parts of it. This is problematic if there is a URL like + // https://example.com/@test@@@123/test@test, punycode will truncate this to https://example.com/@test which + // is security issue because parts of the URL are actually missing from the text that we display. That's why + // we use punycode on valid URLs(that don't have '@' as part of the host) only for the host part of the URL. + try { + const url = new URL(decoratedText); + + const { host } = url; + + if (host) { + url.host = punycode.toASCII(host); + text = url.toString(); + } + } catch (e) { + // Not a valid URL + } + + if (!text) { + // This will be the case for invalid URLs or URLs without a host (emails for example). In this case beacuse + // of the issue with PunycodeJS that truncates parts of the text when there is '@' we split the text by '@' + // and use punycode for every separate part to prevent homograph attacks. + text = decoratedText.split('@').map(punycode.toASCII) + .join('@'); + } + return ( - { punycode.toASCII(decoratedText) } + { text } ); }