|
1 | 1 | /** |
2 | | - * Dangerous Unicode control characters that can be used by hackers |
3 | | - * to perform trojan source. |
| 2 | + * This code has been copy-pasted from: |
| 3 | + * https://github.com/lirantal/anti-trojan-source |
| 4 | + * |
| 5 | + * WHY? |
| 6 | + * Because of the high number of dependencies. |
4 | 7 | */ |
5 | | -const kUnsafeUnicodeControlCharacters = [ |
| 8 | + |
| 9 | +// CONSTANTS |
| 10 | +// Explicit list of dangerous confusable characters |
| 11 | +const kExplicitConfusableChars = [ |
| 12 | + // ARABIC LETTER MARK |
| 13 | + "\u061C", |
| 14 | + // LEFT-TO-RIGHT MARK |
| 15 | + "\u200E", |
| 16 | + // RIGHT-TO-LEFT MARK |
| 17 | + "\u200F", |
| 18 | + // LEFT-TO-RIGHT EMBEDDING |
6 | 19 | "\u202A", |
| 20 | + // RIGHT-TO-LEFT EMBEDDING |
7 | 21 | "\u202B", |
| 22 | + // POP DIRECTIONAL FORMATTING |
| 23 | + "\u202C", |
| 24 | + // LEFT-TO-RIGHT OVERRIDE |
8 | 25 | "\u202D", |
| 26 | + // RIGHT-TO-LEFT OVERRIDE |
9 | 27 | "\u202E", |
10 | | - "\u202C", |
| 28 | + // LEFT-TO-RIGHT ISOLATE |
11 | 29 | "\u2066", |
| 30 | + // RIGHT-TO-LEFT ISOLATE |
12 | 31 | "\u2067", |
| 32 | + // FIRST STRONG ISOLATE |
13 | 33 | "\u2068", |
| 34 | + // POP DIRECTIONAL ISOLATE |
14 | 35 | "\u2069", |
15 | | - "\u200E", |
16 | | - "\u200F", |
17 | | - "\u061C" |
| 36 | + // ZERO WIDTH SPACE |
| 37 | + "\u200B", |
| 38 | + // ZERO WIDTH NON-JOINER |
| 39 | + "\u200C", |
| 40 | + // ZERO WIDTH JOINER |
| 41 | + "\u200D", |
| 42 | + // WORD JOINER |
| 43 | + "\u2060", |
| 44 | + // INVISIBLE SEPARATOR |
| 45 | + "\u2063", |
| 46 | + // SOFT HYPHEN |
| 47 | + "\u00AD", |
| 48 | + // NO-BREAK SPACE |
| 49 | + "\u00A0", |
| 50 | + // VARIATION SELECTOR-1 |
| 51 | + "\uFE00", |
| 52 | + // VARIATION SELECTOR-2 |
| 53 | + "\uFE01", |
| 54 | + // VARIATION SELECTOR-3 |
| 55 | + "\uFE02", |
| 56 | + // VARIATION SELECTOR-4 |
| 57 | + "\uFE03", |
| 58 | + // VARIATION SELECTOR-5 |
| 59 | + "\uFE04", |
| 60 | + // VARIATION SELECTOR-6 |
| 61 | + "\uFE05", |
| 62 | + // VARIATION SELECTOR-7 |
| 63 | + "\uFE06", |
| 64 | + // VARIATION SELECTOR-8 |
| 65 | + "\uFE07", |
| 66 | + // VARIATION SELECTOR-9 |
| 67 | + "\uFE08", |
| 68 | + // VARIATION SELECTOR-10 |
| 69 | + "\uFE09", |
| 70 | + // VARIATION SELECTOR-11 |
| 71 | + "\uFE0A", |
| 72 | + // VARIATION SELECTOR-12 |
| 73 | + "\uFE0B", |
| 74 | + // VARIATION SELECTOR-13 |
| 75 | + "\uFE0C", |
| 76 | + // VARIATION SELECTOR-14 |
| 77 | + "\uFE0D", |
| 78 | + // VARIATION SELECTOR-15 |
| 79 | + "\uFE0E", |
| 80 | + // VARIATION SELECTOR-16 |
| 81 | + "\uFE0F", |
| 82 | + // ZERO WIDTH NO-BREAK SPACE (BOM) |
| 83 | + "\uFEFF", |
| 84 | + // MONGOLIAN VOWEL SEPARATOR |
| 85 | + "\u180E" |
| 86 | +]; |
| 87 | +// Combine all confusable characters |
| 88 | +const kConfusableChars = [ |
| 89 | + ...kExplicitConfusableChars, |
| 90 | + ...generateExtendedVariationSelectors() |
18 | 91 | ]; |
19 | 92 |
|
| 93 | +// Generate Extended Variation Selectors (U+E0100 to U+E01EF) |
| 94 | +// These are Variation Selectors Supplement - 240 characters |
| 95 | +function* generateExtendedVariationSelectors(): Iterable<string> { |
| 96 | + for (let codePoint = 0xe0100; codePoint <= 0xe01ef; codePoint++) { |
| 97 | + yield String.fromCodePoint(codePoint); |
| 98 | + } |
| 99 | +} |
| 100 | + |
20 | 101 | export function verify( |
21 | | - sourceString: string |
| 102 | + sourceTextToSearch: string |
22 | 103 | ): boolean { |
23 | | - for (const unsafeCharacter of kUnsafeUnicodeControlCharacters) { |
24 | | - if (sourceString.includes(unsafeCharacter)) { |
| 104 | + for (const confusableChar of kConfusableChars) { |
| 105 | + if (sourceTextToSearch.includes(confusableChar)) { |
25 | 106 | return true; |
26 | 107 | } |
27 | 108 | } |
|
0 commit comments