Skip to content

Commit

Permalink
fix(chat-URLs): Use punycode only on host name.
Browse files Browse the repository at this point in the history
This is workaround for PunycodeJS which truncates parts of the URL when
it contains '@'.
  • Loading branch information
hristoterezov committed Jun 29, 2023
1 parent fab8a98 commit 368d47c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
31 changes: 30 additions & 1 deletion react/features/base/react/components/web/Linkify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,42 @@ export default class Linkify extends Component<IProps> {
* @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 (
<a
href = { decoratedHref }
key = { key }
rel = 'noopener noreferrer'
target = '_blank'>
{ punycode.toASCII(decoratedText) }
{ text }
</a>
);
}
Expand Down

0 comments on commit 368d47c

Please sign in to comment.