@@ -24,10 +24,366 @@ describe('#mountComponentsInHtml', () => {
2424 expect ( replaceSpecialCharacters ( '{"nh_count":15966,"classes":"mt-3"}' ) ) . toEqual (
2525 '{"nh_count":15966,"classes":"mt-3"}' ,
2626 ) ;
27- expect ( replaceSpecialCharacters ( '"<>'"\\n\\\\n\\"&' ) ) . toEqual ( '"<>\'"\\n\\n "&' ) ;
27+ expect ( replaceSpecialCharacters ( '"<>'"\\n\\\\n\\"&' ) ) . toEqual ( '"<>\'"\\n\\\\n\\ "&' ) ;
2828 expect ( replaceSpecialCharacters ( 'abcd 1234 <&""&>' ) ) . toEqual ( 'abcd 1234 <&""&>' ) ;
2929 } ) ;
3030
31+ it ( '#replaceSpecialCharacters and escapeHtml should return same result' , ( ) => {
32+ // eslint-disable-next-line global-require
33+ const { replaceSpecialCharacters } = require ( '../mountComponentsInHtml' ) ;
34+ // eslint-disable-next-line global-require
35+ const { escapeHtml } = require ( '../inlineSvelteComponent' ) ;
36+ const start = '{"prop":"This is a string with \\"escaped\\" quotes"}' ;
37+ const escaped = escapeHtml ( start ) ;
38+ const replaced = replaceSpecialCharacters ( escaped ) ;
39+ expect ( start ) . toEqual ( replaced ) ;
40+ } ) ;
41+
42+ it ( '#replaceSpecialCharacters and escapeHtml should return same result. #245' , ( ) => {
43+ // eslint-disable-next-line global-require
44+ const { replaceSpecialCharacters } = require ( '../mountComponentsInHtml' ) ;
45+ // eslint-disable-next-line global-require
46+ const { escapeHtml } = require ( '../inlineSvelteComponent' ) ;
47+
48+ const naughtyObjsOrStrings = [
49+ {
50+ type : 'auditAdvisory' ,
51+ data : {
52+ resolution : { id : 566 , path : 'hoek' , dev : false , optional : false , bundled : false } ,
53+ advisory : {
54+ findings : [ { version : '2.16.3' , paths : [ 'hoek' ] , dev : false , optional : false , bundled : false } ] ,
55+ id : 566 ,
56+ created : '2018-04-20T21:25:58.421Z' ,
57+ updated : '2019-02-14T16:00:33.922Z' ,
58+ deleted : null ,
59+ title : 'Prototype Pollution' ,
60+ found_by : { name : 'HoLyVieR' } ,
61+ reported_by : { name : 'HoLyVieR' } ,
62+ module_name : 'hoek' ,
63+ cves : [ ] ,
64+ vulnerable_versions : '<= 4.2.0 || >= 5.0.0 < 5.0.3' ,
65+ patched_versions : '> 4.2.0 < 5.0.0 || >= 5.0.3' ,
66+ overview :
67+ 'Versions of `hoek` prior to 4.2.1 and 5.0.3 are vulnerable to prototype pollution.\n\nThe `merge` function, and the `applyToDefaults` and `applyToDefaultsWithShallow` functions which leverage `merge` behind the scenes, are vulnerable to a prototype pollution attack when provided an _unvalidated_ payload created from a JSON string containing the `__proto__` property.\n\nThis can be demonstrated like so:\n\n```javascript\nvar Hoek = require(\'hoek\');\nvar malicious_payload = \'{"__proto__":{"oops":"It works !"}}\';\n\nvar a = {};\nconsole.log("Before : " + a.oops);\nHoek.merge({}, JSON.parse(malicious_payload));\nconsole.log("After : " + a.oops);\n```\n\nThis type of attack can be used to overwrite existing properties causing a potential denial of service.' ,
68+ recommendation : 'Update to version 4.2.1, 5.0.3 or later.' ,
69+ references : '' ,
70+ access : 'public' ,
71+ severity : 'moderate' ,
72+ cwe : 'CWE-471' ,
73+ metadata : { module_type : '' , exploitability : 5 , affected_components : '' } ,
74+ url : 'https://npmjs.com/advisories/566' ,
75+ } ,
76+ } ,
77+ } ,
78+ 'OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5' ,
79+ 'OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5' ,
80+ 'TmFO' ,
81+ 'SW5maW5pdHk=' ,
82+ 'LUluZmluaXR5' ,
83+ 'SU5G' ,
84+ 'MSNJTkY=' ,
85+ 'LTEjSU5E' ,
86+ 'MSNRTkFO' ,
87+ 'MSNTTkFO' ,
88+ 'MSNJTkQ=' ,
89+ 'MHgw' ,
90+ 'MHhmZmZmZmZmZg==' ,
91+ 'MHhmZmZmZmZmZmZmZmZmZmZm' ,
92+ 'MHhhYmFkMWRlYQ==' ,
93+ 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5' ,
94+ 'MSwwMDAuMDA=' ,
95+ 'MSAwMDAuMDA=' ,
96+ 'MScwMDAuMDA=' ,
97+ 'MSwwMDAsMDAwLjAw' ,
98+ 'MSAwMDAgMDAwLjAw' ,
99+ 'MScwMDAnMDAwLjAw' ,
100+ 'MS4wMDAsMDA=' ,
101+ 'MSAwMDAsMDA=' ,
102+ 'MScwMDAsMDA=' ,
103+ 'MS4wMDAuMDAwLDAw' ,
104+ 'MSAwMDAgMDAwLDAw' ,
105+ 'MScwMDAnMDAwLDAw' ,
106+ 'MDEwMDA=' ,
107+ 'MDg=' ,
108+ 'MDk=' ,
109+ 'Mi4yMjUwNzM4NTg1MDcyMDExZS0zMDg=' ,
110+ 'LC4vOydbXS09' ,
111+ 'PD4/OiJ7fXxfKw==' ,
112+ 'IUAjJCVeJiooKWB+' ,
113+ 'AQIDBAUGBwgODxAREhMUFRYXGBkaGxwdHh9/' ,
114+ 'woDCgcKCwoPChMKGwofCiMKJworCi8KMwo3CjsKPwpDCkcKSwpPClMKVwpbCl8KYwpnCmsKbwpzC' ,
115+ 'ncKewp8=' ,
116+ 'CwwgwoXCoOGagOKAgOKAgeKAguKAg+KAhOKAheKAhuKAh+KAiOKAieKAiuKAi+KAqOKAqeKAr+KB' ,
117+ 'n+OAgA==' ,
118+ 'wq3YgNiB2ILYg9iE2IXYnNud3I/hoI7igIvigIzigI3igI7igI/igKrigKvigKzigK3igK7igaDi' ,
119+ 'gaHigaLigaPigaTigabigafigajiganigarigavigaziga3iga7iga/vu7/vv7nvv7rvv7vwkYK9' ,
120+ '8JuyoPCbsqHwm7Ki8Juyo/CdhbPwnYW08J2FtfCdhbbwnYW38J2FuPCdhbnwnYW686CAgfOggKDz' ,
121+ 'oICh86CAovOggKPzoICk86CApfOggKbzoICn86CAqPOggKnzoICq86CAq/OggKzzoICt86CArvOg' ,
122+ 'gK/zoICw86CAsfOggLLzoICz86CAtPOggLXzoIC286CAt/OggLjzoIC586CAuvOggLvzoIC886CA' ,
123+ 'vfOggL7zoIC/86CBgPOggYHzoIGC86CBg/OggYTzoIGF86CBhvOggYfzoIGI86CBifOggYrzoIGL' ,
124+ '86CBjPOggY3zoIGO86CBj/OggZDzoIGR86CBkvOggZPzoIGU86CBlfOggZbzoIGX86CBmPOggZnz' ,
125+ 'oIGa86CBm/OggZzzoIGd86CBnvOggZ/zoIGg86CBofOggaLzoIGj86CBpPOggaXzoIGm86CBp/Og' ,
126+ 'gajzoIGp86CBqvOggavzoIGs86CBrfOgga7zoIGv86CBsPOggbHzoIGy86CBs/OggbTzoIG186CB' ,
127+ 'tvOggbfzoIG486CBufOggbrzoIG786CBvPOggb3zoIG+86CBvw==' ,
128+ '77u/' ,
129+ '77++' ,
130+ 'zqniiYjDp+KImuKIq8ucwrXiiaTiiaXDtw==' ,
131+ 'w6XDn+KIgsaSwqnLmeKIhsuawqzigKbDpg==' ,
132+ 'xZPiiJHCtMKu4oCgwqXCqMuGw7jPgOKAnOKAmA==' ,
133+ 'wqHihKLCo8Ki4oiewqfCtuKAosKqwrrigJPiiaA=' ,
134+ 'wrjLm8OH4peKxLHLnMOCwq/LmMK/' ,
135+ 'w4XDjcOOw4/LncOTw5Tvo7/DksOaw4bimIM=' ,
136+ 'xZLigJ7CtOKAsMuHw4HCqMuGw5jiiI/igJ3igJk=' ,
137+ 'YOKBhOKCrOKAueKAuu+sge+sguKAocKwwrfigJrigJTCsQ==' ,
138+ '4oWb4oWc4oWd4oWe' ,
139+ 'undefined' ,
140+ 'undef' ,
141+ 'null' ,
142+ 'NULL' ,
143+ '(null)' ,
144+ 'nil' ,
145+ 'NIL' ,
146+ 'true' ,
147+ 'false' ,
148+ 'True' ,
149+ 'False' ,
150+ 'TRUE' ,
151+ 'FALSE' ,
152+ 'None' ,
153+ 'hasOwnProperty' ,
154+ '\\' ,
155+ '\\\\' ,
156+ '0' ,
157+ '1' ,
158+ '1.00' ,
159+ '$1.00' ,
160+ '1/2' ,
161+ '1E2' ,
162+ '1E02' ,
163+ '1E+02' ,
164+ '-1' ,
165+ '-1.00' ,
166+ '-$1.00' ,
167+ '-1/2' ,
168+ '-1E2' ,
169+ '-1E02' ,
170+ '-1E+02' ,
171+ '1/0' ,
172+ '0/0' ,
173+ '-2147483648/-1' ,
174+ '-9223372036854775808/-1' ,
175+ '-0' ,
176+ '-0.0' ,
177+ '+0' ,
178+ '+0.0' ,
179+ '0.00' ,
180+ '0..0' ,
181+ '.' ,
182+ '0.0.0' ,
183+ '0,00' ,
184+ '0,,0' ,
185+ ',' ,
186+ '0,0,0' ,
187+ '0.0/0' ,
188+ '1.0/0.0' ,
189+ '0.0/0.0' ,
190+ '1,0/0,0' ,
191+ '0,0/0,0' ,
192+ '--1' ,
193+ '-' ,
194+ '-.' ,
195+ '-,' ,
196+ '999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999' ,
197+ 'NaN' ,
198+ 'Infinity' ,
199+ '-Infinity' ,
200+ 'INF' ,
201+ '1#INF' ,
202+ '-1#IND' ,
203+ '1#QNAN' ,
204+ '1#SNAN' ,
205+ '1#IND' ,
206+ '0x0' ,
207+ '0xffffffff' ,
208+ '0xffffffffffffffff' ,
209+ '0xabad1dea' ,
210+ '123456789012345678901234567890123456789' ,
211+ '1,000.00' ,
212+ '1 000.00' ,
213+ "1'000.00" ,
214+ '1,000,000.00' ,
215+ '1 000 000.00' ,
216+ "1'000'000.00" ,
217+ '1.000,00' ,
218+ '1 000,00' ,
219+ "1'000,00" ,
220+ '1.000.000,00' ,
221+ '1 000 000,00' ,
222+ "1'000'000,00" ,
223+ '01000' ,
224+ '08' ,
225+ '09' ,
226+ '2.2250738585072011e-308' ,
227+ ",./;'[]\\-=" ,
228+ '<>?:"{}|_+' ,
229+ '\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f' ,
230+ '' ,
231+ 'The quick brown fox jumps over the lazy dog' ,
232+ '𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠' ,
233+ '𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌' ,
234+ '𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈' ,
235+ '𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰' ,
236+ '𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘' ,
237+ '𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐' ,
238+ '⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢' ,
239+ '<script>alert(123)</script>' ,
240+ '<script>alert('123');</script>' ,
241+ '<img src=x onerror=alert(123) />' ,
242+ '<svg><script>123<1>alert(123)</script>' ,
243+ '"><script>alert(123)</script>' ,
244+ "'><script>alert(123)</script>" ,
245+ '><script>alert(123)</script>' ,
246+ '</script><script>alert(123)</script>' ,
247+ '< / script >< script >alert(123)< / script >' ,
248+ ' onfocus=JaVaSCript:alert(123) autofocus' ,
249+ '" onfocus=JaVaSCript:alert(123) autofocus' ,
250+ "' onfocus=JaVaSCript:alert(123) autofocus" ,
251+ '<script>alert(123)</script>' ,
252+ '<sc<script>ript>alert(123)</sc</script>ript>' ,
253+ '--><script>alert(123)</script>' ,
254+ '";alert(123);t="' ,
255+ "';alert(123);t='" ,
256+ // eslint-disable-next-line no-script-url
257+ 'JavaSCript:alert(123)' ,
258+ ';alert(123);' ,
259+ 'src=JaVaSCript:prompt(132)' ,
260+ '"><script>alert(123);</script x="' ,
261+ "'><script>alert(123);</script x='" ,
262+ '><script>alert(123);</script x=' ,
263+ '" autofocus onkeyup="javascript:alert(123)' ,
264+ "' autofocus onkeyup='javascript:alert(123)" ,
265+ '<script\\x20type="text/javascript">javascript:alert(1);</script>' ,
266+ '<script\\x3Etype="text/javascript">javascript:alert(1);</script>' ,
267+ '<script\\x0Dtype="text/javascript">javascript:alert(1);</script>' ,
268+ '<script\\x09type="text/javascript">javascript:alert(1);</script>' ,
269+ '<script\\x0Ctype="text/javascript">javascript:alert(1);</script>' ,
270+ '<script\\x2Ftype="text/javascript">javascript:alert(1);</script>' ,
271+ '<script\\x0Atype="text/javascript">javascript:alert(1);</script>' ,
272+ 'ABC<div style="x\\x3Aexpression(javascript:alert(1)">DEF' ,
273+ 'ABC<div style="x:expression\\x5C(javascript:alert(1)">DEF' ,
274+ 'ABC<div style="x:expression\\x00(javascript:alert(1)">DEF' ,
275+ 'ABC<div style="x:exp\\x00ression(javascript:alert(1)">DEF' ,
276+ 'ABC<div style="x:exp\\x5Cression(javascript:alert(1)">DEF' ,
277+ 'ABC<div style="x:\\x0Aexpression(javascript:alert(1)">DEF' ,
278+ 'ABC<div style="x:\\x09expression(javascript:alert(1)">DEF' ,
279+ 'ABC<div style="x:\\xE3\\x80\\x80expression(javascript:alert(1)">' ,
280+ '-' ,
281+ '--' ,
282+ '--version' ,
283+ '--help' ,
284+ '$USER' ,
285+ '/dev/null; touch /tmp/blns.fail ; echo' ,
286+ '$(touch /tmp/blns.fail)' ,
287+ '@{[system "touch /tmp/blns.fail"]}' ,
288+ 'eval("puts \'hello world\'")' ,
289+ 'System("ls -al /")' ,
290+ 'Kernel.exec("ls -al /")' ,
291+ 'Kernel.exit(1)' ,
292+ "%x('ls -al /')" ,
293+ '<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>' ,
294+ '$HOME' ,
295+ "$ENV{'HOME'}" ,
296+ '%d' ,
297+ '%s%s%s%s%s' ,
298+ '{0}' ,
299+ '%*.*s' ,
300+ '%@' ,
301+ '%n' ,
302+ 'File:///' ,
303+ '../../../../../../../../../../../etc/passwd%00' ,
304+ '../../../../../../../../../../../etc/hosts' ,
305+ '() { 0; }; touch /tmp/blns.shellshock1.fail;' ,
306+ '() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }' ,
307+ "<<< %s(un='%s') = %u" ,
308+ '+++ATH0' ,
309+ 'CON' ,
310+ 'PRN' ,
311+ 'AUX' ,
312+ 'CLOCK$' ,
313+ 'NUL' ,
314+ 'A:' ,
315+ 'ZZ:' ,
316+ 'COM1' ,
317+ 'LPT1' ,
318+ 'LPT2' ,
319+ 'LPT3' ,
320+ 'COM2' ,
321+ 'COM3' ,
322+ 'COM4' ,
323+ 'DCC SEND STARTKEYLOGGER 0 0 0' ,
324+ 'Scunthorpe General Hospital' ,
325+ 'Penistone Community Church' ,
326+ 'Lightwater Country Park' ,
327+ 'Jimmy Clitheroe' ,
328+ 'Horniman Museum' ,
329+ 'shitake mushrooms' ,
330+ 'RomansInSussex.co.uk' ,
331+ 'http://www.cum.qc.ca/' ,
332+ 'Craig Cockburn, Software Specialist' ,
333+ 'Linda Callahan' ,
334+ 'Dr. Herman I. Libshitz' ,
335+ 'magna cum laude' ,
336+ 'Super Bowl XXX' ,
337+ 'medieval erection of parapets' ,
338+ 'evaluate' ,
339+ 'mocha' ,
340+ 'expression' ,
341+ 'Arsenal canal' ,
342+ 'classic' ,
343+ 'Tyson Gay' ,
344+ 'Dick Van Dyke' ,
345+ 'basement' ,
346+ "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you." ,
347+ 'Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue' ,
348+ 'But now...\u001b[20Cfor my greatest trick...\u001b[8m' ,
349+ 'The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]' ,
350+ 'Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗' ,
351+ '🏳0🌈️' ,
352+ '### No JSON flag' +
353+ '```' +
354+ `{
355+ "hello": "world" // This is a comment
356+ }` +
357+ '```' +
358+ '### `json` flag' +
359+ '```json' +
360+ `
361+ {
362+ "hello": "world" // This is a comment
363+ }
364+ ` +
365+ '```' +
366+ '### `jsonc` flag' +
367+ '```jsonc' +
368+ `{
369+ "hello": "world" // This is a comment
370+ }` +
371+ '```' +
372+ '### `json5` flag' +
373+ '```json5' +
374+ `{
375+ "hello": "world" // This is a comment
376+ }` +
377+ '```' ,
378+ ] ;
379+
380+ for ( const start of naughtyObjsOrStrings ) {
381+ const escaped = escapeHtml ( JSON . stringify ( start ) ) ;
382+ const replaced = JSON . parse ( replaceSpecialCharacters ( escaped ) ) ;
383+ expect ( start ) . toEqual ( replaced ) ;
384+ }
385+ } ) ;
386+
31387 it ( 'mounts a single component in HTML correctly' , ( ) => {
32388 hydrated = [ ] ;
33389 // eslint-disable-next-line global-require
0 commit comments