Skip to content

Commit fd98d04

Browse files
committed
fix: prevent linking text with directional change char
1 parent 14160b1 commit fd98d04

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

src/parser/parse-matches.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { UrlMatch, UrlMatchType } from '../match/url-match';
33
import { Match } from '../match/match';
44
import { remove, assertNever } from '../utils';
55
import {
6+
hasDirectionalChar,
67
httpSchemeRe,
78
isDomainLabelChar,
89
isDomainLabelStartChar,
@@ -411,7 +412,7 @@ export function parseMatches(text: string, args: ParseMatchesArgs): Match[] {
411412
} else if (isUrlSuffixStartChar(char)) {
412413
// '/', '?', or '#'
413414
stateMachine.state = State.Path;
414-
} else if (isDomainLabelChar(char)) {
415+
} else if (isDomainLabelChar(char) || hasDirectionalChar(char)) {
415416
// Stay in the DomainLabelChar state
416417
} else {
417418
// Anything else, end the domain name

src/parser/uri-utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ export function isDomainLabelChar(char: string): boolean {
110110
return char === '_' || isDomainLabelStartChar(char);
111111
}
112112

113+
export function hasDirectionalChar(char: string) {
114+
return /[\u202a-\u202e\u200e-\u200f]/g.test(char);
115+
}
116+
113117
/**
114118
* Determines if the character is a path character ("pchar") as defined by
115119
* https://tools.ietf.org/html/rfc3986#appendix-A
@@ -168,6 +172,11 @@ export function isValidSchemeUrl(url: string): boolean {
168172
return false;
169173
}
170174

175+
// If url contains directional change character prevent it from linking
176+
if (hasDirectionalChar(url)) {
177+
return false;
178+
}
179+
171180
const isAuthorityMatch = !!schemeMatch![1];
172181
const host = schemeMatch![2];
173182
if (isAuthorityMatch) {
@@ -213,6 +222,11 @@ export function isValidTldMatch(url: string): boolean {
213222
return false;
214223
}
215224

225+
// If url contains directional change character prevent it from linking
226+
if (hasDirectionalChar(url)) {
227+
return false;
228+
}
229+
216230
const tld = hostLabels[hostLabels.length - 1];
217231
if (!isKnownTld(tld)) {
218232
return false;

tests/autolinker-url.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,13 @@ describe('Autolinker Url Matching >', () => {
10321032
});
10331033
});
10341034

1035+
describe('unicode exploits', () => {
1036+
fit('text with directional change characters should not be linked', () => {
1037+
expect(autolinker.link('foo.com\u202Ebar.com')).toBe('foo.com\u202Ebar.com');
1038+
expect(autolinker.link('foo.com\u202Emoc.rab')).toBe('foo.com\u202Emoc.rab');
1039+
});
1040+
});
1041+
10351042
function generateCombinationTests({
10361043
schemes,
10371044
hosts,

0 commit comments

Comments
 (0)