DomainLockNodeTemplate.spec.ts 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  1. import 'reflect-metadata';
  2. import format from 'string-template';
  3. import { assert } from 'chai';
  4. import { ServiceIdentifiers } from '../../../../../src/container/ServiceIdentifiers';
  5. import { ICryptUtils } from '../../../../../src/interfaces/utils/ICryptUtils';
  6. import { IInversifyContainerFacade } from '../../../../../src/interfaces/container/IInversifyContainerFacade';
  7. import { IObfuscationResult } from '../../../../../src/interfaces/source-code/IObfuscationResult';
  8. import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
  9. import { DomainLockTemplate } from '../../../../../src/custom-code-helpers/domain-lock/templates/DomainLockTemplate';
  10. import { InversifyContainerFacade } from '../../../../../src/container/InversifyContainerFacade';
  11. import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
  12. import { readFileAsString } from '../../../../helpers/readFileAsString';
  13. /**
  14. * @param templateData
  15. * @param {string} callsControllerFunctionName
  16. * @param {string} documentTemplate
  17. * @returns {Function}
  18. */
  19. function getFunctionFromTemplate (
  20. templateData: any,
  21. callsControllerFunctionName: string,
  22. documentTemplate: string
  23. ): Function {
  24. const domainLockTemplate: string = format(DomainLockTemplate(), templateData);
  25. return Function(`
  26. ${documentTemplate}
  27. var ${callsControllerFunctionName} = (function(){
  28. return function (context, fn){
  29. return function () {
  30. return fn.apply(context, arguments);
  31. };
  32. }
  33. })();
  34. ${domainLockTemplate}
  35. `);
  36. }
  37. describe('DomainLockTemplate', () => {
  38. const singleCallControllerFunctionName: string = 'callsController';
  39. const thatThisTemplate = 'const that = this;';
  40. let cryptUtils: ICryptUtils;
  41. before(() => {
  42. const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
  43. inversifyContainerFacade.load('', '', {});
  44. cryptUtils = inversifyContainerFacade.get<ICryptUtils>(ServiceIdentifiers.ICryptUtils);
  45. });
  46. describe('Variant #1: current domain matches with `domainsString`', () => {
  47. const domainsString: string = ['www.example.com'].join(';');
  48. const domainDest: string = 'about:blank';
  49. const currentDomain: string = 'www.example.com';
  50. let testFunc: Function;
  51. let root: any;
  52. before(() => {
  53. const [
  54. hiddenDomainsString,
  55. domainsStringDiff
  56. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  57. const [
  58. hiddenDomainDest,
  59. domainDestDiff
  60. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  61. root = {
  62. document: {
  63. domain: currentDomain,
  64. location: undefined,
  65. },
  66. };
  67. testFunc = getFunctionFromTemplate(
  68. {
  69. domainLockFunctionName: 'domainLockFunction',
  70. domainsStringDiff,
  71. domains: hiddenDomainsString,
  72. domainDestDiff,
  73. hiddenDomainDest,
  74. globalVariableTemplate: '',
  75. singleCallControllerFunctionName
  76. },
  77. singleCallControllerFunctionName,
  78. thatThisTemplate
  79. );
  80. });
  81. it('should correctly run code inside template', () => {
  82. assert.doesNotThrow(() => testFunc.apply(root));
  83. assert.isUndefined(root.document.location);
  84. });
  85. });
  86. describe('Variant #2: current domain matches with base domain of `domainsString`', () => {
  87. const domainsString: string = ['.example.com'].join(';');
  88. const domainDest: string = 'about:blank';
  89. const currentDomain: string = 'www.example.com';
  90. let testFunc: Function;
  91. let root: any;
  92. before(() => {
  93. const [
  94. hiddenDomainsString,
  95. domainsStringDiff
  96. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  97. const [
  98. hiddenDomainDest,
  99. domainDestDiff
  100. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  101. root = {
  102. document: {
  103. domain: currentDomain,
  104. location: undefined,
  105. },
  106. };
  107. testFunc = getFunctionFromTemplate(
  108. {
  109. domainLockFunctionName: 'domainLockFunction',
  110. domainsStringDiff,
  111. domains: hiddenDomainsString,
  112. domainDestDiff,
  113. hiddenDomainDest,
  114. globalVariableTemplate: '',
  115. singleCallControllerFunctionName
  116. },
  117. singleCallControllerFunctionName,
  118. thatThisTemplate
  119. );
  120. });
  121. it('should correctly run code inside template', () => {
  122. assert.doesNotThrow(() => testFunc.apply(root));
  123. assert.isUndefined(root.document.location);
  124. });
  125. });
  126. describe('Variant #3: current domain matches with root domain of `domainsString`', () => {
  127. const domainsString: string = ['.example.com'].join(';');
  128. const domainDest: string = 'about:blank';
  129. const currentDomain: string = 'example.com';
  130. let testFunc: Function;
  131. let root: any;
  132. before(() => {
  133. const [
  134. hiddenDomainsString,
  135. domainsStringDiff
  136. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  137. const [
  138. hiddenDomainDest,
  139. domainDestDiff
  140. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  141. root = {
  142. document: {
  143. domain: currentDomain,
  144. location: undefined,
  145. },
  146. };
  147. testFunc = getFunctionFromTemplate(
  148. {
  149. domainLockFunctionName: 'domainLockFunction',
  150. domainsStringDiff,
  151. domains: hiddenDomainsString,
  152. domainDestDiff,
  153. hiddenDomainDest,
  154. globalVariableTemplate: '',
  155. singleCallControllerFunctionName
  156. },
  157. singleCallControllerFunctionName,
  158. thatThisTemplate
  159. );
  160. });
  161. it('should correctly run code inside template', () => {
  162. assert.doesNotThrow(() => testFunc.apply(root));
  163. assert.isUndefined(root.document.location);
  164. });
  165. });
  166. describe('Variant #4: current root domain matches with `domainsString`', () => {
  167. describe('Variant #1', () => {
  168. const domainsString: string = ['example.com'].join(';');
  169. const domainDest: string = 'about:blank';
  170. const currentDomain: string = 'example.com';
  171. let testFunc: Function;
  172. let root: any;
  173. before(() => {
  174. const [
  175. hiddenDomainsString,
  176. domainsStringDiff
  177. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  178. const [
  179. hiddenDomainDest,
  180. domainDestDiff
  181. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  182. root = {
  183. document: {
  184. domain: currentDomain,
  185. location: undefined,
  186. },
  187. };
  188. testFunc = getFunctionFromTemplate(
  189. {
  190. domainLockFunctionName: 'domainLockFunction',
  191. domainsStringDiff,
  192. domains: hiddenDomainsString,
  193. domainDestDiff,
  194. domainDest: hiddenDomainDest,
  195. globalVariableTemplate: '',
  196. singleCallControllerFunctionName
  197. },
  198. singleCallControllerFunctionName,
  199. thatThisTemplate
  200. );
  201. });
  202. it('should correctly run code inside template', () => {
  203. assert.doesNotThrow(() => testFunc.apply(root));
  204. assert.isUndefined(root.document.location);
  205. });
  206. });
  207. describe('Variant #2', () => {
  208. const domainsString: string = ['example.com', '.example.com'].join(';');
  209. const domainDest: string = 'about:blank';
  210. const currentDomain: string = 'subdomain.example.com';
  211. let testFunc: Function;
  212. let root: any;
  213. before(() => {
  214. const [
  215. hiddenDomainsString,
  216. domainsStringDiff
  217. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  218. const [
  219. hiddenDomainDest,
  220. domainDestDiff
  221. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  222. root = {
  223. document: {
  224. domain: currentDomain,
  225. location: undefined,
  226. },
  227. };
  228. testFunc = getFunctionFromTemplate(
  229. {
  230. domainLockFunctionName: 'domainLockFunction',
  231. domainsStringDiff,
  232. domains: hiddenDomainsString,
  233. domainDestDiff,
  234. domainDest: hiddenDomainDest,
  235. globalVariableTemplate: '',
  236. singleCallControllerFunctionName
  237. },
  238. singleCallControllerFunctionName,
  239. thatThisTemplate
  240. );
  241. });
  242. it('should correctly run code inside template', () => {
  243. assert.doesNotThrow(() => testFunc.apply(root));
  244. assert.isUndefined(root.document.location);
  245. });
  246. });
  247. describe('Variant #3', () => {
  248. const domainsString: string = ['.example.com', 'example.com'].join(';');
  249. const domainDest: string = 'about:blank';
  250. const currentDomain: string = 'subdomain.example.com';
  251. let testFunc: Function;
  252. let root: any;
  253. before(() => {
  254. const [
  255. hiddenDomainsString,
  256. domainsStringDiff
  257. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  258. const [
  259. hiddenDomainDest,
  260. domainDestDiff
  261. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  262. root = {
  263. document: {
  264. domain: currentDomain,
  265. location: undefined,
  266. },
  267. };
  268. testFunc = getFunctionFromTemplate(
  269. {
  270. domainLockFunctionName: 'domainLockFunction',
  271. domainsStringDiff,
  272. domains: hiddenDomainsString,
  273. domainDestDiff,
  274. domainDest: hiddenDomainDest,
  275. globalVariableTemplate: '',
  276. singleCallControllerFunctionName
  277. },
  278. singleCallControllerFunctionName,
  279. thatThisTemplate
  280. );
  281. });
  282. it('should correctly run code inside template', () => {
  283. assert.doesNotThrow(() => testFunc.apply(root));
  284. assert.isUndefined(root.document.location);
  285. });
  286. });
  287. describe('Variant #4', () => {
  288. const domainsString: string = ['sub1.example.com', 'sub2.example.com'].join(';');
  289. const domainDest: string = 'about:blank';
  290. const currentDomain: string = 'sub1.example.com';
  291. let testFunc: Function;
  292. let root: any;
  293. before(() => {
  294. const [
  295. hiddenDomainsString,
  296. domainsStringDiff
  297. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  298. const [
  299. hiddenDomainDest,
  300. domainDestDiff
  301. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  302. root = {
  303. document: {
  304. domain: currentDomain,
  305. location: undefined,
  306. },
  307. };
  308. testFunc = getFunctionFromTemplate(
  309. {
  310. domainLockFunctionName: 'domainLockFunction',
  311. domainsStringDiff,
  312. domains: hiddenDomainsString,
  313. domainDestDiff,
  314. domainDest: hiddenDomainDest,
  315. globalVariableTemplate: '',
  316. singleCallControllerFunctionName
  317. },
  318. singleCallControllerFunctionName,
  319. thatThisTemplate
  320. );
  321. });
  322. it('should correctly run code inside template', () => {
  323. assert.doesNotThrow(() => testFunc.apply(root));
  324. assert.isUndefined(root.document.location);
  325. });
  326. });
  327. });
  328. describe('Variant #5: current domain matches with base domain of `domainsString` item', () => {
  329. const domainsString: string = ['www.test.com', '.example.com'].join(';');
  330. const domainDest: string = 'about:blank';
  331. const currentDomain: string = 'subdomain.example.com';
  332. let testFunc: Function;
  333. let root: any;
  334. before(() => {
  335. const [
  336. hiddenDomainsString,
  337. domainsStringDiff
  338. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  339. const [
  340. hiddenDomainDest,
  341. domainDestDiff
  342. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  343. root = {
  344. document: {
  345. domain: currentDomain,
  346. location: undefined,
  347. },
  348. };
  349. testFunc = getFunctionFromTemplate(
  350. {
  351. domainLockFunctionName: 'domainLockFunction',
  352. domainsStringDiff,
  353. domains: hiddenDomainsString,
  354. domainDestDiff,
  355. hiddenDomainDest,
  356. globalVariableTemplate: '',
  357. singleCallControllerFunctionName
  358. },
  359. singleCallControllerFunctionName,
  360. thatThisTemplate
  361. );
  362. });
  363. it('should correctly run code inside template', () => {
  364. assert.doesNotThrow(() => testFunc.apply(root));
  365. assert.isUndefined(root.document.location);
  366. });
  367. });
  368. describe('Variant #6: current domain doesn\'t match with `domainsString`', () => {
  369. describe('Variant #1', () => {
  370. const domainsString: string = ['www.example.com'].join(';');
  371. const domainDest: string = 'about:blank';
  372. const currentDomain: string = 'www.test.com';
  373. let testFunc: Function;
  374. let root: any;
  375. before(() => {
  376. const [
  377. hiddenDomainsString,
  378. domainsStringDiff
  379. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  380. const [
  381. hiddenDomainDest,
  382. domainDestDiff
  383. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  384. root = {
  385. document: {
  386. domain: currentDomain,
  387. location: undefined,
  388. },
  389. };
  390. testFunc = getFunctionFromTemplate(
  391. {
  392. domainLockFunctionName: 'domainLockFunction',
  393. domainsStringDiff,
  394. domains: hiddenDomainsString,
  395. domainDestDiff,
  396. domainDest: hiddenDomainDest,
  397. globalVariableTemplate: '',
  398. singleCallControllerFunctionName
  399. },
  400. singleCallControllerFunctionName,
  401. thatThisTemplate
  402. );
  403. });
  404. it('should change document.location', () => {
  405. assert.doesNotThrow(() => testFunc.apply(root));
  406. assert.equal(root.document.location, domainDest);
  407. });
  408. });
  409. describe('Variant #2', () => {
  410. const domainsString: string = ['sub1.test.com', 'sub2.test.com'].join(';');
  411. const domainDest: string = 'about:blank';
  412. const currentDomain: string = 'sub3.test.com';
  413. let testFunc: Function;
  414. let root: any;
  415. before(() => {
  416. const [
  417. hiddenDomainsString,
  418. domainsStringDiff
  419. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  420. const [
  421. hiddenDomainDest,
  422. domainDestDiff
  423. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  424. root = {
  425. document: {
  426. domain: currentDomain,
  427. location: undefined,
  428. },
  429. };
  430. testFunc = getFunctionFromTemplate({
  431. domainLockFunctionName: 'domainLockFunction',
  432. domainsStringDiff,
  433. domains: hiddenDomainsString,
  434. domainDestDiff,
  435. domainDest: hiddenDomainDest,
  436. globalVariableTemplate: '',
  437. singleCallControllerFunctionName
  438. },
  439. singleCallControllerFunctionName,
  440. thatThisTemplate
  441. );
  442. });
  443. it('should change document.location', () => {
  444. assert.doesNotThrow(() => testFunc.apply(root));
  445. assert.equal(root.document.location, domainDest);
  446. });
  447. });
  448. describe('Variant #3', () => {
  449. const domainsString: string = ['www.example.com', '.example.com', 'sub.test.com'].join(';');
  450. const domainDest: string = 'about:blank';
  451. const currentDomain: string = 'www.test.com';
  452. let testFunc: Function;
  453. let root: any;
  454. before(() => {
  455. const [
  456. hiddenDomainsString,
  457. domainsStringDiff
  458. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  459. const [
  460. hiddenDomainDest,
  461. domainDestDiff
  462. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  463. root = {
  464. document: {
  465. domain: currentDomain,
  466. location: undefined,
  467. },
  468. };
  469. testFunc = getFunctionFromTemplate(
  470. {
  471. domainLockFunctionName: 'domainLockFunction',
  472. domainsStringDiff,
  473. domains: hiddenDomainsString,
  474. domainDestDiff,
  475. domainDest: hiddenDomainDest,
  476. globalVariableTemplate: '',
  477. singleCallControllerFunctionName
  478. },
  479. singleCallControllerFunctionName,
  480. thatThisTemplate
  481. );
  482. });
  483. it('should change document.location', () => {
  484. assert.doesNotThrow(() => testFunc.apply(root));
  485. assert.equal(root.document.location, domainDest);
  486. });
  487. });
  488. describe('Variant #4', () => {
  489. const domainsString: string = ['.example.com'].join(';');
  490. const domainDest: string = 'about:blank';
  491. const currentDomain: string = 'example1.com';
  492. let testFunc: Function;
  493. let root: any;
  494. before(() => {
  495. const [
  496. hiddenDomainsString,
  497. domainsStringDiff
  498. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  499. const [
  500. hiddenDomainDest,
  501. domainDestDiff
  502. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  503. root = {
  504. document: {
  505. domain: currentDomain,
  506. location: undefined,
  507. },
  508. };
  509. testFunc = getFunctionFromTemplate(
  510. {
  511. domainLockFunctionName: 'domainLockFunction',
  512. domainsStringDiff,
  513. domains: hiddenDomainsString,
  514. domainDestDiff,
  515. domainDest: hiddenDomainDest,
  516. globalVariableTemplate: '',
  517. singleCallControllerFunctionName
  518. },
  519. singleCallControllerFunctionName,
  520. thatThisTemplate
  521. );
  522. });
  523. it('should change document.location', () => {
  524. assert.doesNotThrow(() => testFunc.apply(root));
  525. assert.equal(root.document.location, domainDest);
  526. });
  527. });
  528. describe('Variant #5', () => {
  529. const domainsString: string = ['example.com'].join(';');
  530. const domainDest: string = 'about:blank';
  531. const currentDomain: string = 'sub.example.com';
  532. let testFunc: Function;
  533. let root: any;
  534. before(() => {
  535. const [
  536. hiddenDomainsString,
  537. domainsStringDiff
  538. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  539. const [
  540. hiddenDomainDest,
  541. domainDestDiff
  542. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  543. root = {
  544. document: {
  545. domain: currentDomain,
  546. location: undefined,
  547. },
  548. };
  549. testFunc = getFunctionFromTemplate(
  550. {
  551. domainLockFunctionName: 'domainLockFunction',
  552. domainsStringDiff,
  553. domains: hiddenDomainsString,
  554. domainDestDiff,
  555. domainDest: hiddenDomainDest,
  556. globalVariableTemplate: '',
  557. singleCallControllerFunctionName
  558. },
  559. singleCallControllerFunctionName,
  560. thatThisTemplate
  561. );
  562. });
  563. it('should change document.location', () => {
  564. assert.doesNotThrow(() => testFunc.apply(root));
  565. assert.equal(root.document.location, domainDest);
  566. });
  567. });
  568. });
  569. describe('Variant #7: location.hostname', () => {
  570. describe('Variant #1: current location.hostname matches with `domainsString`', () => {
  571. const domainsString: string = ['www.example.com'].join(';');
  572. const domainDest: string = 'about:blank';
  573. const currentHostName: string = 'www.example.com';
  574. let testFunc: Function;
  575. let root: any;
  576. before(() => {
  577. const [
  578. hiddenDomainsString,
  579. domainsStringDiff
  580. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  581. const [
  582. hiddenDomainDest,
  583. domainDestDiff
  584. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  585. root = {
  586. document: {
  587. location: {
  588. hostname: currentHostName,
  589. },
  590. },
  591. };
  592. testFunc = getFunctionFromTemplate(
  593. {
  594. domainLockFunctionName: 'domainLockFunction',
  595. domainsStringDiff,
  596. domains: hiddenDomainsString,
  597. domainDestDiff,
  598. domainDest: hiddenDomainDest,
  599. globalVariableTemplate: '',
  600. singleCallControllerFunctionName
  601. },
  602. singleCallControllerFunctionName,
  603. thatThisTemplate
  604. );
  605. });
  606. it('should correctly run code inside template', () => {
  607. assert.doesNotThrow(() => testFunc.apply(root));
  608. assert.isObject(root.document.location);
  609. });
  610. });
  611. describe('Variant #2: current location.hostname doesn\'t match with `domainsString`', () => {
  612. const domainsString: string = ['www.example.com'].join(';');
  613. const domainDest: string = 'about:blank';
  614. const currentHostName: string = 'www.test.com';
  615. let testFunc: Function;
  616. let root: any;
  617. before(() => {
  618. const [
  619. hiddenDomainsString,
  620. domainsStringDiff
  621. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  622. const [
  623. hiddenDomainDest,
  624. domainDestDiff
  625. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  626. root = {
  627. document: {
  628. location: {
  629. hostname: currentHostName,
  630. },
  631. },
  632. };
  633. testFunc = getFunctionFromTemplate(
  634. {
  635. domainLockFunctionName: 'domainLockFunction',
  636. domainsStringDiff,
  637. domains: hiddenDomainsString,
  638. domainDestDiff,
  639. domainDest: hiddenDomainDest,
  640. globalVariableTemplate: '',
  641. singleCallControllerFunctionName
  642. },
  643. singleCallControllerFunctionName,
  644. thatThisTemplate
  645. );
  646. });
  647. it('should change document.location', () => {
  648. assert.doesNotThrow(() => testFunc.apply(root));
  649. assert.equal(root.document.location, domainDest);
  650. });
  651. });
  652. });
  653. describe('Variant #8: domain and location.hostname presented', () => {
  654. describe('Variant #1: current domain matches with `domainsString`', () => {
  655. const domainsString: string = ['www.example.com'].join(';');
  656. const domainDest: string = 'about:blank';
  657. const currentHostName: string = 'www.example.com';
  658. let testFunc: Function;
  659. let root: any;
  660. before(() => {
  661. const [
  662. hiddenDomainsString,
  663. domainsStringDiff
  664. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  665. const [
  666. hiddenDomainDest,
  667. domainDestDiff
  668. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  669. root = {
  670. document: {
  671. domain: currentHostName,
  672. location: {
  673. hostname: currentHostName,
  674. },
  675. },
  676. };
  677. testFunc = getFunctionFromTemplate(
  678. {
  679. domainLockFunctionName: 'domainLockFunction',
  680. domainsStringDiff,
  681. domains: hiddenDomainsString,
  682. domainDestDiff,
  683. domainDest: hiddenDomainDest,
  684. globalVariableTemplate: '',
  685. singleCallControllerFunctionName
  686. },
  687. singleCallControllerFunctionName,
  688. thatThisTemplate
  689. );
  690. });
  691. it('should correctly run code inside template', () => {
  692. assert.doesNotThrow(() => testFunc.apply(root));
  693. assert.isObject(root.document.location);
  694. });
  695. });
  696. describe('Variant #2: current domain doesn\'t match with `domainsString`', () => {
  697. const domainsString: string = ['www.example.com'].join(';');
  698. const domainDest: string = 'about:blank';
  699. const currentHostName: string = 'www.test.com';
  700. let testFunc: Function;
  701. let root: any;
  702. before(() => {
  703. const [
  704. hiddenDomainsString,
  705. domainsStringDiff
  706. ] = cryptUtils.hideString(domainsString, domainsString.length * 3);
  707. const [
  708. hiddenDomainDest,
  709. domainDestDiff
  710. ] = cryptUtils.hideString(domainDest, domainDest.length * 3);
  711. root = {
  712. document: {
  713. domain: currentHostName,
  714. location: {
  715. hostname: currentHostName,
  716. },
  717. },
  718. };
  719. testFunc = getFunctionFromTemplate(
  720. {
  721. domainLockFunctionName: 'domainLockFunction',
  722. domainsStringDiff,
  723. domains: hiddenDomainsString,
  724. domainDestDiff,
  725. domainDest: hiddenDomainDest,
  726. globalVariableTemplate: '',
  727. singleCallControllerFunctionName
  728. },
  729. singleCallControllerFunctionName,
  730. thatThisTemplate
  731. );
  732. });
  733. it('should change document.location', () => {
  734. assert.doesNotThrow(() => testFunc.apply(root));
  735. assert.equal(root.document.location, domainDest);
  736. });
  737. });
  738. });
  739. describe('Prevailing kind of variables', () => {
  740. const getCodeTemplate = (obfuscatedCode: string) => `
  741. global.document = {
  742. domain: 'obfuscator.io'
  743. };
  744. ${obfuscatedCode}
  745. `;
  746. describe('`var` kind', () => {
  747. let obfuscatedCode: string,
  748. domainLockVariableRegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *new *RegExp/;
  749. beforeEach(() => {
  750. const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-var.js');
  751. const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  752. code,
  753. {
  754. ...NO_ADDITIONAL_NODES_PRESET,
  755. domainLock: ['obfuscator.io'],
  756. stringArray: true,
  757. stringArrayThreshold: 1
  758. }
  759. );
  760. obfuscatedCode = obfuscationResult.getObfuscatedCode();
  761. });
  762. it('Should return correct kind of variables for domain lock code', () => {
  763. assert.match(obfuscatedCode, domainLockVariableRegExp);
  764. });
  765. it('Should does not break on obfuscating', () => {
  766. assert.doesNotThrow(() => eval(getCodeTemplate(obfuscatedCode)));
  767. });
  768. });
  769. describe('`const` kind', () => {
  770. let obfuscatedCode: string,
  771. domainLockVariableRegExp: RegExp = /const _0x([a-f0-9]){4,6} *= *new *RegExp/;
  772. beforeEach(() => {
  773. const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-const.js');
  774. const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  775. code,
  776. {
  777. ...NO_ADDITIONAL_NODES_PRESET,
  778. domainLock: ['obfuscator.io'],
  779. stringArray: true,
  780. stringArrayThreshold: 1
  781. }
  782. );
  783. obfuscatedCode = obfuscationResult.getObfuscatedCode();
  784. });
  785. it('Should return correct kind of variables for domain lock code', () => {
  786. assert.match(obfuscatedCode, domainLockVariableRegExp);
  787. });
  788. it('Should does not break on obfuscating', () => {
  789. assert.doesNotThrow(() => eval(getCodeTemplate(obfuscatedCode)));
  790. });
  791. });
  792. describe('`let` kind', () => {
  793. let obfuscatedCode: string,
  794. domainLockVariableRegExp: RegExp = /const _0x([a-f0-9]){4,6} *= *new *RegExp/;
  795. beforeEach(() => {
  796. const code: string = readFileAsString(__dirname + '/fixtures/prevailing-kind-of-variables-let.js');
  797. const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  798. code,
  799. {
  800. ...NO_ADDITIONAL_NODES_PRESET,
  801. domainLock: ['obfuscator.io'],
  802. stringArray: true,
  803. stringArrayThreshold: 1
  804. }
  805. );
  806. obfuscatedCode = obfuscationResult.getObfuscatedCode();
  807. });
  808. it('Should return correct kind of variables for domain lock code', () => {
  809. assert.match(obfuscatedCode, domainLockVariableRegExp);
  810. });
  811. it('Should does not break on obfuscating', () => {
  812. assert.doesNotThrow(() => eval(getCodeTemplate(obfuscatedCode)));
  813. });
  814. });
  815. });
  816. });