logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

html_test.exs (9084B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.HTMLTest do
  5. alias Pleroma.HTML
  6. alias Pleroma.Object
  7. alias Pleroma.Web.CommonAPI
  8. use Pleroma.DataCase, async: true
  9. import Pleroma.Factory
  10. @html_sample """
  11. <b>this is in bold</b>
  12. <p>this is a paragraph</p>
  13. this is a linebreak<br />
  14. this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
  15. this is a link with not allowed "rel" attribute: <a href="http://example.com/" rel="tag noallowed">example.com</a>
  16. this is an image: <img src="http://example.com/image.jpg"><br />
  17. this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"><br />
  18. <script>alert('hacked')</script>
  19. """
  20. @html_onerror_sample """
  21. <img src="http://example.com/image.jpg" onerror="alert('hacked')">
  22. """
  23. @html_stillimage_sample """
  24. <img class="still-image" src="http://example.com/image.jpg">
  25. """
  26. @html_span_class_sample """
  27. <span class="animate-spin">hi</span>
  28. """
  29. @html_span_microformats_sample """
  30. <span class="h-card"><a class="u-url mention">@<span>foo</span></a></span>
  31. """
  32. @html_span_invalid_microformats_sample """
  33. <span class="h-card"><a class="u-url mention animate-spin">@<span>foo</span></a></span>
  34. """
  35. describe "StripTags scrubber" do
  36. test "works as expected" do
  37. expected = """
  38. this is in bold
  39. this is a paragraph
  40. this is a linebreak
  41. this is a link with allowed &quot;rel&quot; attribute: example.com
  42. this is a link with not allowed &quot;rel&quot; attribute: example.com
  43. this is an image:
  44. this is an inline emoji:
  45. alert(&#39;hacked&#39;)
  46. """
  47. assert expected == HTML.strip_tags(@html_sample)
  48. end
  49. test "does not allow attribute-based XSS" do
  50. expected = "\n"
  51. assert expected == HTML.strip_tags(@html_onerror_sample)
  52. end
  53. end
  54. describe "TwitterText scrubber" do
  55. test "normalizes HTML as expected" do
  56. expected = """
  57. this is in bold
  58. <p>this is a paragraph</p>
  59. this is a linebreak<br/>
  60. this is a link with allowed &quot;rel&quot; attribute: <a href="http://example.com/" rel="tag">example.com</a>
  61. this is a link with not allowed &quot;rel&quot; attribute: <a href="http://example.com/">example.com</a>
  62. this is an image: <img src="http://example.com/image.jpg"/><br/>
  63. this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"/><br/>
  64. alert(&#39;hacked&#39;)
  65. """
  66. assert expected == HTML.filter_tags(@html_sample, Pleroma.HTML.Scrubber.TwitterText)
  67. end
  68. test "does not allow attribute-based XSS" do
  69. expected = """
  70. <img src="http://example.com/image.jpg"/>
  71. """
  72. assert expected == HTML.filter_tags(@html_onerror_sample, Pleroma.HTML.Scrubber.TwitterText)
  73. end
  74. test "does not allow spans with invalid classes" do
  75. expected = """
  76. <span>hi</span>
  77. """
  78. assert expected ==
  79. HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.TwitterText)
  80. end
  81. test "does not allow images with invalid classes" do
  82. expected = """
  83. <img src="http://example.com/image.jpg"/>
  84. """
  85. assert expected ==
  86. HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText)
  87. end
  88. test "does allow microformats" do
  89. expected = """
  90. <span class="h-card"><a class="u-url mention">@<span>foo</span></a></span>
  91. """
  92. assert expected ==
  93. HTML.filter_tags(@html_span_microformats_sample, Pleroma.HTML.Scrubber.TwitterText)
  94. end
  95. test "filters invalid microformats markup" do
  96. expected = """
  97. <span class="h-card"><a>@<span>foo</span></a></span>
  98. """
  99. assert expected ==
  100. HTML.filter_tags(
  101. @html_span_invalid_microformats_sample,
  102. Pleroma.HTML.Scrubber.TwitterText
  103. )
  104. end
  105. end
  106. describe "default scrubber" do
  107. test "normalizes HTML as expected" do
  108. expected = """
  109. <b>this is in bold</b>
  110. <p>this is a paragraph</p>
  111. this is a linebreak<br/>
  112. this is a link with allowed &quot;rel&quot; attribute: <a href="http://example.com/" rel="tag">example.com</a>
  113. this is a link with not allowed &quot;rel&quot; attribute: <a href="http://example.com/">example.com</a>
  114. this is an image: <img src="http://example.com/image.jpg"/><br/>
  115. this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"/><br/>
  116. alert(&#39;hacked&#39;)
  117. """
  118. assert expected == HTML.filter_tags(@html_sample, Pleroma.HTML.Scrubber.Default)
  119. end
  120. test "does not allow attribute-based XSS" do
  121. expected = """
  122. <img src="http://example.com/image.jpg"/>
  123. """
  124. assert expected == HTML.filter_tags(@html_onerror_sample, Pleroma.HTML.Scrubber.Default)
  125. end
  126. test "does not allow spans with invalid classes" do
  127. expected = """
  128. <span>hi</span>
  129. """
  130. assert expected == HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.Default)
  131. end
  132. test "does not allow images with invalid classes" do
  133. expected = """
  134. <img src="http://example.com/image.jpg"/>
  135. """
  136. assert expected ==
  137. HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText)
  138. end
  139. test "does allow microformats" do
  140. expected = """
  141. <span class="h-card"><a class="u-url mention">@<span>foo</span></a></span>
  142. """
  143. assert expected ==
  144. HTML.filter_tags(@html_span_microformats_sample, Pleroma.HTML.Scrubber.Default)
  145. end
  146. test "filters invalid microformats markup" do
  147. expected = """
  148. <span class="h-card"><a>@<span>foo</span></a></span>
  149. """
  150. assert expected ==
  151. HTML.filter_tags(
  152. @html_span_invalid_microformats_sample,
  153. Pleroma.HTML.Scrubber.Default
  154. )
  155. end
  156. end
  157. describe "extract_first_external_url_from_object" do
  158. test "extracts the url" do
  159. user = insert(:user)
  160. {:ok, activity} =
  161. CommonAPI.post(user, %{
  162. status:
  163. "I think I just found the best github repo https://github.com/komeiji-satori/Dress"
  164. })
  165. object = Object.normalize(activity, fetch: false)
  166. {:ok, url} = HTML.extract_first_external_url_from_object(object)
  167. assert url == "https://github.com/komeiji-satori/Dress"
  168. end
  169. test "skips mentions" do
  170. user = insert(:user)
  171. other_user = insert(:user)
  172. {:ok, activity} =
  173. CommonAPI.post(user, %{
  174. status:
  175. "@#{other_user.nickname} install misskey! https://github.com/syuilo/misskey/blob/develop/docs/setup.en.md"
  176. })
  177. object = Object.normalize(activity, fetch: false)
  178. {:ok, url} = HTML.extract_first_external_url_from_object(object)
  179. assert url == "https://github.com/syuilo/misskey/blob/develop/docs/setup.en.md"
  180. refute url == other_user.ap_id
  181. end
  182. test "skips hashtags" do
  183. user = insert(:user)
  184. {:ok, activity} =
  185. CommonAPI.post(user, %{
  186. status: "#cofe https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140"
  187. })
  188. object = Object.normalize(activity, fetch: false)
  189. {:ok, url} = HTML.extract_first_external_url_from_object(object)
  190. assert url == "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140"
  191. end
  192. test "skips microformats hashtags" do
  193. user = insert(:user)
  194. {:ok, activity} =
  195. CommonAPI.post(user, %{
  196. status:
  197. "<a href=\"https://pleroma.gov/tags/cofe\" rel=\"tag\">#cofe</a> https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140",
  198. content_type: "text/html"
  199. })
  200. object = Object.normalize(activity, fetch: false)
  201. {:ok, url} = HTML.extract_first_external_url_from_object(object)
  202. assert url == "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140"
  203. end
  204. test "does not crash when there is an HTML entity in a link" do
  205. user = insert(:user)
  206. {:ok, activity} = CommonAPI.post(user, %{status: "\"http://cofe.com/?boomer=ok&foo=bar\""})
  207. object = Object.normalize(activity, fetch: false)
  208. assert {:ok, nil} = HTML.extract_first_external_url_from_object(object)
  209. end
  210. test "skips attachment links" do
  211. user = insert(:user)
  212. {:ok, activity} =
  213. CommonAPI.post(user, %{
  214. status:
  215. "<a href=\"https://pleroma.gov/media/d24caa3a498e21e0298377a9ca0149a4f4f8b767178aacf837542282e2d94fb1.png?name=image.png\" class=\"attachment\">image.png</a>"
  216. })
  217. object = Object.normalize(activity, fetch: false)
  218. assert {:ok, nil} = HTML.extract_first_external_url_from_object(object)
  219. end
  220. end
  221. end