|
1 | 1 | class HTMLSmugglingBlocker {
|
2 | 2 | constructor() {
|
3 |
| - this.blocked = false; |
4 |
| - this.suspiciousPatterns = [ |
5 |
| - { pattern: /[aA][tT][oO][bB]\s*\([^)]+\).*new\s+[uU]int8[aA]rray/is, weight: 3 }, |
6 |
| - { pattern: /[bB]lob\s*\(\s*\[[^\]]+\]\s*,\s*\{\s*type\s*:\s*['"]application\/octet-stream['"]\s*\}\s*\)/is, weight: 3 }, |
7 |
| - { pattern: /[uU][rR][lL]\.create[oO]bject[uU][rR][lL]\s*\(\s*[^)]+\)/is, weight: 2 }, |
| 3 | + this.blocked = false; this.suspiciousPatterns = [ |
| 4 | + { pattern: /atob\s*\([^)]+\).*new\s+uint8array/is, weight: 3 }, |
| 5 | + { pattern: /atob\s*\(\s*['"]([A-Za-z0-9+/=]{100,})['"].*\)/i, weight: 3 }, |
| 6 | + { pattern: /new\s+blob\s*\(\s*\[\s*(?:data|atob\s*\()/i, weight: 3 }, |
| 7 | + { pattern: /url\.createobjecturl\s*\(\s*(?:my)?blob\s*\)/i, weight: 3 }, |
| 8 | + { pattern: /location(?:\s*\[\s*["']href["']\s*\])?\s*=\s*url/i, weight: 3 }, |
| 9 | + { pattern: /url\.revokeobjecturl\s*\(\s*url\s*\)/i, weight: 2 }, |
| 10 | + { pattern: /window\s*\[\s*(?:["']\w+["']\s*\+\s*)+["']\w+["']\s*\]/i, weight: 3 }, |
| 11 | + { pattern: /document\s*\[\s*(?:["']\w+["']\s*\+\s*)+["']\w+["']\s*\]\s*\(\s*window\s*\[\s*(?:['"]at['"].*['"]o['"].*['"]b['"]\s*\]|\s*(?:["']\w+["']\s*\+\s*)+["']\w+["']\s*\])\s*\(['"][A-Za-z0-9+/=]+['"]\)\s*\)/i, weight: 4 }, |
| 12 | + { pattern: /var\s+\w+=\w+;?\s*\(function\(\w+,\w+\)\{.*while\(!!\[\]\)\{try\{.*parseint.*\}catch\(\w+\)\{.*\}\}\}\(.*\)\);?/is, weight: 4 }, |
| 13 | + { pattern: /blob\s*\(\s*\[[^\]]+\]\s*,\s*\{\s*type\s*:\s*['"](?:application\/octet-stream|text\/html|octet\/stream)['"](?:\s*,\s*encoding\s*:\s*['"]base64['"])?\s*\}\s*\)/is, weight: 3 }, |
8 | 14 | { pattern: /\.style\s*=\s*['"]display:\s*none['"].*\.href\s*=.*\.download\s*=/is, weight: 3 },
|
9 |
| - { pattern: /\.click\s*\(\s*\).*[uU][rR][lL]\.revoke[oO]bject[uU][rR][lL]/is, weight: 3 }, |
10 |
| - { pattern: /href\s*=\s*["']data:application\/octet-stream;base64,/i, weight: 3 }, |
11 |
| - { pattern: /[wW]eb[aA]ssembly\.[iI]nstantiate/i, weight: 2 }, |
12 |
| - { pattern: /navigator\.[sS]ervice[wW]orker\.register/i, weight: 2 }, |
| 15 | + { pattern: /\.click\s*\(\s*\).*url\.revokeobjecturl/is, weight: 3 }, |
| 16 | + { pattern: /href\s*=\s*["']data:(?:application\/octet-stream|image\/svg\+xml);base64,/i, weight: 3 }, |
| 17 | + { pattern: /webassembly\s*\.\s*(?:instantiate(?:streaming)?|instance)/i, weight: 3 }, |
| 18 | + { pattern: /navigator\.serviceworker\.register/i, weight: 2 }, |
13 | 19 | { pattern: /srcdoc\s*=\s*["'][^"']*<script/i, weight: 3 },
|
14 |
| - { pattern: /function\s+(?:[bB]64[tT]o[aA]rray|[xX][oO][rR])\s*\([^)]*\)\s*{[\s\S]*?return\s+(?:bytes\.buffer|result);?}/i, weight: 3 }, |
15 |
| - { pattern: /document\.create[eE]lement\(['"']embed['"']\)/i, weight: 3 }, |
16 |
| - { pattern: /\.set[aA]ttribute\(['"']src['"']\s*,\s*.*\)/i, weight: 2 }, |
17 |
| - { pattern: /[sS]tring\.from[cC]har[cC]ode\(.*\)/i, weight: 2 }, |
18 |
| - { pattern: /\.char[cC]ode[aA]t\(.*\)/i, weight: 2 }, |
19 |
| - { pattern: /document\.get[eE]lement[bB]y[iI]d\(['"']passwordid['"']\)\.value/i, weight: 3 }, |
20 |
| - { pattern: /[aA][tT][oO][bB]\s*\(\s*['"]([A-Za-z0-9+/=]{100,})['"].*\)/i, weight: 3 }, |
21 |
| - { pattern: /new\s+[bB]lob\s*\(\s*\[\s*[aA][tT][oO][bB]\s*\(/i, weight: 3 }, |
22 |
| - { pattern: /import\s*\(\s*[uU][rR][lL]\.create[oO]bject[uU][rR][lL]\s*\(/i, weight: 3 }, |
23 |
| - { pattern: /[wW]eb[aA]ssembly\.[iI]nstance/i, weight: 2 }, |
| 20 | + { pattern: /function\s+(?:b64toarray|xor|base64toarraybuffer)\s*\([^)]*\)\s*{[\s\S]*?return\s+(?:bytes\.buffer|result);?}/i, weight: 3 }, |
| 21 | + { pattern: /document\.createelement\(['"']embed['"']\)/i, weight: 3 }, |
| 22 | + { pattern: /\.setattribute\(['"']src['"']\s*,\s*.*\)/i, weight: 2 }, |
| 23 | + { pattern: /window\.navigator\.mssaveoropenblob\s*\(\s*blob\s*,\s*filename\s*\)/i, weight: 3 }, |
| 24 | + { pattern: /(?:window\.)?url\.createobjecturl\s*\(\s*(?:blob|[^)]+)\s*\)/i, weight: 2 }, |
| 25 | + { pattern: /(?:a|element)\.download\s*=\s*(?:filename|['"][^'"]+['"])/i, weight: 2 }, |
| 26 | + { pattern: /string\.fromcharcode\(.*\)/i, weight: 2 }, |
| 27 | + { pattern: /\.charcodeat\(.*\)/i, weight: 2 }, |
| 28 | + { pattern: /document\.getelementbyid\(['"']passwordid['"']\)\.value/i, weight: 3 }, |
| 29 | + { pattern: /import\s*\(\s*url\.createobjecturl\s*\(/i, weight: 3 }, |
24 | 30 | { pattern: /\w+\s*\(\s*\w+\s*\(\s*['"][A-Za-z0-9+/=]{50,}['"]\s*\)\s*\)/i, weight: 3 },
|
25 |
| - { pattern: /[uU][rR][lL]\.create[oO]bject[uU][rR][lL]\s*\(\s*new\s+[bB]lob/i, weight: 3 }, |
26 |
| - { pattern: /\.download\s*=\s*['"][^'"]+['"]/i, weight: 2 }, |
27 |
| - { pattern: /window\.[aA][tT][oO][bB]\s*\(/i, weight: 2 }, |
28 |
| - { pattern: /[uU]int8[aA]rray\s*\(\s*[^)]+\)/i, weight: 2 }, |
29 |
| - { pattern: /ms[sS]ave[oO]r[oO]pen[bB]lob|ms[sS]ave[bB]lob/i, weight: 3 }, |
30 |
| - { pattern: /\.click\(\s*\)\s*;\s*window\.[uU][rR][lL]\.revoke[oO]bject[uU][rR][lL]/i, weight: 3 }, |
31 |
| - { pattern: /base64[tT]o[aA]rray[bB]uffer/i, weight: 3 }, |
32 |
| - { pattern: /new\s+[uU]int8[aA]rray\s*\(\s*len\s*\)/i, weight: 3 }, |
33 |
| - { pattern: /window\.[uU][rR][lL]\.create[oO]bject[uU][rR][lL]\s*\(\s*blob\s*\)/i, weight: 3 }, |
34 |
| - { pattern: /a\.download\s*=\s*file[nN]ame/i, weight: 3 }, |
35 |
| - { pattern: /window\.[uU][rR][lL]\.revoke[oO]bject[uU][rR][lL]\s*\(\s*url\s*\)/i, weight: 3 }, |
36 |
| - { pattern: /[dD][aA][tT][aA]\s*:\s*[aA][pP][pP][lL][iI][cC][aA][tT][iI][oO][nN]\/[oO][cC][tT][eE][tT]-[sS][tT][rR][eE][aA][mM]\s*;\s*[bB][aA][sS][eE]64\s*,/i, weight: 3 }, |
| 31 | + { pattern: /(?:window\.)?atob\s*\(/i, weight: 2 }, |
| 32 | + { pattern: /uint8[aA]rray\s*\(\s*(?:(?!len)[^)])*\)/i, weight: 2 }, |
| 33 | + { pattern: /mssaveoropenblob|mssaveblob/i, weight: 3 }, |
| 34 | + { pattern: /base64toarraybuffer/i, weight: 3 }, |
37 | 35 | { pattern: /wasm[_-]?exec\.js/i, weight: 2 },
|
38 | 36 | { pattern: /\.wasm/i, weight: 3 },
|
39 |
| - { pattern: /[wW]eb[aA]ssembly\s*\.\s*(instantiate(?:[sS]treaming)?|[iI]nstance)/i, weight: 3 }, |
40 |
| - { pattern: /new\s+[gG]o\s*\(\s*\)/i, weight: 3 }, |
| 37 | + { pattern: /new\s+go\s*\(\s*\)/i, weight: 3 }, |
41 | 38 | { pattern: /go\s*\.\s*run\s*\(/i, weight: 3 },
|
42 | 39 | { pattern: /<embed[^>]*base64/i, weight: 3 },
|
43 |
| - { pattern: /[dD][aA][tT][aA]\s*:\s*[iI][mM][aA][gG][eE]\/[sS][vV][gG]\+[xX][mM][lL]\s*;\s*[bB][aA][sS][eE]64\s*,/i, weight: 3 }, |
44 | 40 | { pattern: /xmlhttprequest\(\).*\.responsetype\s*=\s*['"]arraybuffer['"]/i, weight: 3 },
|
45 | 41 | { pattern: /new\s+dataview\(.*\).*\.getuint8\(.*\).*\.setuint8\(/i, weight: 3 },
|
46 | 42 | { pattern: /[^\w](\w+)\s*=\s*(\w+)\s*\^\s*(\w+)/i, weight: 2 },
|
47 |
| - { pattern: /window\.url\.createobjecturl\(.*\).*window\.url\.revokeobjecturl\(/i, weight: 3 }, |
48 | 43 | { pattern: /\.slice\(\s*\w+\s*-\s*\d+\s*,\s*\w+\s*-\s*\d+\s*\)/i, weight: 2 },
|
49 | 44 | { pattern: /for\s*\([^)]+\)\s*\{[^}]*string\.fromcharcode\([^)]+\)/i, weight: 3 },
|
50 |
| - { pattern: /new\s+blob\(\s*\[[^\]]+\]\s*,\s*\{\s*type\s*:\s*['"]application\/octet-stream['"]\s*\}\s*\)/i, weight: 3 }, |
51 | 45 | ];
|
52 | 46 | this.threshold = 4;
|
53 | 47 | this.setupListeners();
|
|
0 commit comments