1
0

PasteViewer.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. 'use strict';
  2. const common = require('../common');
  3. const fc = require('fast-check');
  4. describe('PasteViewer', function () {
  5. describe('run, hide, getText, setText, getFormat, setFormat & isPrettyPrinted', function () {
  6. this.timeout(30000);
  7. beforeEach(() => {
  8. document.body.innerHTML = (
  9. '<div id="placeholder" class="hidden">+++ no document text +++</div>' +
  10. '<div id="prettymessage" class="hidden"><pre id="prettyprint" class="prettyprint linenums:1"></pre></div>' +
  11. '<div id="plaintext" class="hidden"></div>'
  12. );
  13. });
  14. afterEach(() => {
  15. globalThis.cleanup();
  16. });
  17. it('basic plaintext display works', function () {
  18. PrivateBin.PasteViewer.init();
  19. PrivateBin.PasteViewer.setFormat('plaintext');
  20. PrivateBin.PasteViewer.setText('hello');
  21. PrivateBin.PasteViewer.run();
  22. assert.strictEqual(PrivateBin.PasteViewer.getText(), 'hello');
  23. assert.ok(!document.getElementById('prettymessage').classList.contains('hidden'));
  24. });
  25. it('basic markdown display works', function () {
  26. PrivateBin.PasteViewer.init();
  27. PrivateBin.PasteViewer.setFormat('markdown');
  28. PrivateBin.PasteViewer.setText('hello **bold**');
  29. PrivateBin.PasteViewer.run();
  30. assert.strictEqual(PrivateBin.PasteViewer.getText(), 'hello **bold**');
  31. assert.ok(!document.getElementById('plaintext').classList.contains('hidden'));
  32. });
  33. it('initializes with empty text and shows nothing', () => {
  34. fc.assert(fc.property(
  35. common.fcFormats(),
  36. function (format) {
  37. var results = [];
  38. PrivateBin.PasteViewer.init();
  39. PrivateBin.PasteViewer.setFormat(format);
  40. PrivateBin.PasteViewer.setText('');
  41. results.push(
  42. document.getElementById('placeholder').classList.contains('hidden') &&
  43. document.getElementById('prettymessage').classList.contains('hidden') &&
  44. document.getElementById('plaintext').classList.contains('hidden') &&
  45. PrivateBin.PasteViewer.getFormat() === format &&
  46. PrivateBin.PasteViewer.getText() === ''
  47. );
  48. return results.every(element => element);
  49. }
  50. ));
  51. });
  52. it('when no text is given and view is rendered, it shows placeholder', () => {
  53. fc.assert(fc.property(
  54. common.fcFormats(),
  55. function (format) {
  56. var results = [];
  57. PrivateBin.PasteViewer.init();
  58. PrivateBin.PasteViewer.setFormat(format);
  59. PrivateBin.PasteViewer.setText('');
  60. PrivateBin.PasteViewer.run();
  61. results.push(
  62. !document.getElementById('placeholder').classList.contains('hidden') &&
  63. document.getElementById('prettymessage').classList.contains('hidden') &&
  64. document.getElementById('plaintext').classList.contains('hidden')
  65. );
  66. return results.every(element => element);
  67. }
  68. ));
  69. });
  70. it('displays text according to format', () => {
  71. fc.assert(fc.property(
  72. common.fcFormats(),
  73. fc.string({minLength: 1}),
  74. function (format, text) {
  75. var results = [];
  76. PrivateBin.PasteViewer.init();
  77. PrivateBin.PasteViewer.setFormat(format);
  78. PrivateBin.PasteViewer.setText(text);
  79. PrivateBin.PasteViewer.run();
  80. results.push(
  81. document.getElementById('placeholder').classList.contains('hidden') &&
  82. !PrivateBin.PasteViewer.isPrettyPrinted() &&
  83. PrivateBin.PasteViewer.getText() === text
  84. );
  85. if (format === 'markdown') {
  86. results.push(
  87. document.getElementById('prettymessage').classList.contains('hidden') &&
  88. !document.getElementById('plaintext').classList.contains('hidden')
  89. );
  90. } else {
  91. results.push(
  92. !document.getElementById('prettymessage').classList.contains('hidden') &&
  93. document.getElementById('plaintext').classList.contains('hidden')
  94. );
  95. }
  96. return results.every(element => element);
  97. }
  98. ));
  99. });
  100. it('sanitizes XSS', () => {
  101. fc.assert(fc.property(
  102. common.fcFormats(),
  103. fc.string(),
  104. fc.constantFrom(
  105. '<PLAINTEXT>',
  106. '></SCRIPT>">\'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>',
  107. '\'\';!--"<XSS>=&{()}',
  108. '<SCRIPT SRC=http://example.com/xss.js></SCRIPT>',
  109. '\'">><marquee><img src=x onerror=confirm(1)></marquee>">' +
  110. '</plaintext\\></|\\><plaintext/onmouseover=prompt(1)>' +
  111. '<script>prompt(1)</script>@gmail.com<isindex formaction=java' +
  112. // obfuscate script URL from eslint rule: no-script-url
  113. 'script:alert(/XSS/) type=submit>\'-->"></script>' +
  114. '<script>alert(document.cookie)</script>"><img/id="confirm' +
  115. '&lpar;1)"/alt="/"src="/"onerror=eval(id)>\'">',
  116. '<IMG SRC="javascript:alert(\'XSS\');">',
  117. '<IMG SRC=javascript:alert(\'XSS\')>',
  118. '<IMG SRC=JaVaScRiPt:alert(\'XSS\')>',
  119. '<IMG SRC=javascript:alert(&quot;XSS&quot;)>',
  120. '<IMG SRC=`javascript:alert("RSnake says, \'XSS\'")`>',
  121. '<a onmouseover="alert(document.cookie)">xxs link</a>',
  122. '<a onmouseover=alert(document.cookie)>xxs link</a>',
  123. '<IMG """><SCRIPT>alert("XSS")</SCRIPT>">',
  124. '<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>',
  125. '<IMG STYLE="xss:expr/*XSS*/ession(alert(\'XSS\'))">',
  126. '<FRAMESET><FRAME SRC="javascript:alert(\'XSS\');"></FRAMESET>',
  127. '<TABLE BACKGROUND="javascript:alert(\'XSS\')">',
  128. '<TABLE><TD BACKGROUND="javascript:alert(\'XSS\')">',
  129. '<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="httx://xss.rocks/xss.js"></SCRIPT>'
  130. ),
  131. fc.string(),
  132. function (format, prefix, xss, suffix) {
  133. var text = prefix + xss + suffix;
  134. document.body.innerHTML = (
  135. '<div id="placeholder" class="hidden">+++ no document text ' +
  136. '+++</div><div id="prettymessage" class="hidden"><pre ' +
  137. 'id="prettyprint" class="prettyprint linenums:1"></pre>' +
  138. '</div><div id="plaintext" class="hidden"></div>'
  139. );
  140. PrivateBin.PasteViewer.init();
  141. PrivateBin.PasteViewer.setFormat(format);
  142. PrivateBin.PasteViewer.setText(text);
  143. PrivateBin.PasteViewer.run();
  144. var result = document.body.innerHTML.indexOf(xss) === -1;
  145. globalThis.cleanup();
  146. return result;
  147. }
  148. ));
  149. });
  150. });
  151. });