Revert "Merge branch 'revert-a26d5e6b' into 'develop'"
authorWilliam Pitcock <nenolod@dereferenced.org>
Sun, 2 Sep 2018 00:14:25 +0000 (00:14 +0000)
committerWilliam Pitcock <nenolod@dereferenced.org>
Fri, 5 Oct 2018 20:49:34 +0000 (20:49 +0000)
This reverts commit d31bbb1cfe04ca6073a322bcf77239e7d4b79839, reversing
changes made to 340ab3cb9068d444b77213e07beb8c2c3ca128b9.

lib/pleroma/formatter.ex
lib/pleroma/web/common_api/common_api.ex
lib/pleroma/web/common_api/utils.ex
lib/pleroma/web/twitter_api/twitter_api_controller.ex
mix.exs
mix.lock
test/web/common_api/common_api_test.exs

index d5565a2cae9e82c3a20c5e7996c7b0a242ff3d4f..c0a176184f0b32327b8d646c0c04ab0323123b4d 100644 (file)
@@ -192,7 +192,11 @@ defmodule Pleroma.Formatter do
   ]
 
   # TODO: make it use something other than @link_regex
-  def html_escape(text) do
+  def html_escape(text, "text/html") do
+    HtmlSanitizeEx.basic_html(text)
+  end
+
+  def html_escape(text, "text/plain") do
     Regex.split(@link_regex, text, include_captures: true)
     |> Enum.map_every(2, fn chunk ->
       {:safe, part} = Phoenix.HTML.html_escape(chunk)
index 125c57d055366c1fbdd63bdbbf8bb5d8666d6861..2ab50c9682be485489ac21d94bdde4133da04c5d 100644 (file)
@@ -85,7 +85,14 @@ defmodule Pleroma.Web.CommonAPI do
          {to, cc} <- to_for_user_and_mentions(user, mentions, inReplyTo, visibility),
          tags <- Formatter.parse_tags(status, data),
          content_html <-
-           make_content_html(status, mentions, attachments, tags, data["no_attachment_links"]),
+           make_content_html(
+             status,
+             mentions,
+             attachments,
+             tags,
+             data["content_type"] || "text/plain",
+             data["no_attachment_links"]
+           ),
          context <- make_context(inReplyTo),
          cw <- data["spoiler_text"],
          object <-
index 358ca22ac81553a7665d608c03569c9546876a92..667027c022d2ed11d5928d25d722b4e8b9b5ca7a 100644 (file)
@@ -63,9 +63,16 @@ defmodule Pleroma.Web.CommonAPI.Utils do
     end
   end
 
-  def make_content_html(status, mentions, attachments, tags, no_attachment_links \\ false) do
+  def make_content_html(
+        status,
+        mentions,
+        attachments,
+        tags,
+        content_type,
+        no_attachment_links \\ false
+      ) do
     status
-    |> format_input(mentions, tags)
+    |> format_input(mentions, tags, content_type)
     |> maybe_add_attachments(attachments, no_attachment_links)
   end
 
@@ -92,9 +99,9 @@ defmodule Pleroma.Web.CommonAPI.Utils do
     Enum.join([text | attachment_text], "<br>")
   end
 
-  def format_input(text, mentions, tags) do
+  def format_input(text, mentions, tags, "text/plain") do
     text
-    |> Formatter.html_escape()
+    |> Formatter.html_escape("text/plain")
     |> String.replace(~r/\r?\n/, "<br>")
     |> (&{[], &1}).()
     |> Formatter.add_links()
@@ -103,6 +110,25 @@ defmodule Pleroma.Web.CommonAPI.Utils do
     |> Formatter.finalize()
   end
 
+  def format_input(text, mentions, tags, "text/html") do
+    text
+    |> Formatter.html_escape("text/html")
+    |> String.replace(~r/\r?\n/, "<br>")
+    |> (&{[], &1}).()
+    |> Formatter.add_user_links(mentions)
+    |> Formatter.finalize()
+  end
+
+  def format_input(text, mentions, tags, "text/markdown") do
+    text
+    |> Earmark.as_html!()
+    |> Formatter.html_escape("text/html")
+    |> String.replace(~r/\r?\n/, "")
+    |> (&{[], &1}).()
+    |> Formatter.add_user_links(mentions)
+    |> Formatter.finalize()
+  end
+
   def add_tag_links(text, tags) do
     tags =
       tags
index cd2bb5b57eba7a891732a3f967d854bf67b225d8..c6637e38db9f37d8b3773db077612214dcc1789b 100644 (file)
@@ -423,7 +423,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
             {String.trim(name, ":"), url}
           end)
 
-        bio_html = CommonUtils.format_input(bio, mentions, tags)
+        bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain")
         Map.put(params, "bio", bio_html |> Formatter.emojify(emoji))
       else
         params
diff --git a/mix.exs b/mix.exs
index 24c7108a0abd95119f4572d8063cf0e8a59d9911..885df0094a4f743fb1e1555089c52ed01f7814ef 100644 (file)
--- a/mix.exs
+++ b/mix.exs
@@ -48,6 +48,7 @@ defmodule Pleroma.Mixfile do
       {:mogrify, "~> 0.6.1"},
       {:ex_aws, "~> 2.0"},
       {:ex_aws_s3, "~> 2.0"},
+      {:earmark, "~> 1.2"},
       {:ex_machina, "~> 2.2", only: :test},
       {:credo, "~> 0.9.3", only: [:dev, :test]},
       {:mock, "~> 0.3.1", only: :test},
index 1da8e7b0cfc21e2e64c775f3423dca4154854d45..105eaf6657f8032a8351a116c36db77cd85e31cf 100644 (file)
--- a/mix.lock
+++ b/mix.lock
@@ -11,6 +11,7 @@
   "crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]},
   "db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
   "decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
+  "earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
   "ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
   "eternal": {:hex, :eternal, "1.2.0", "e2a6b6ce3b8c248f7dc31451aefca57e3bdf0e48d73ae5043229380a67614c41", [:mix], [], "hexpm"},
   "ex_aws": {:hex, :ex_aws, "2.1.0", "b92651527d6c09c479f9013caa9c7331f19cba38a650590d82ebf2c6c16a1d8a", [:mix], [{:configparser_ex, "~> 2.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.1.0", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"},
index 2a2c40833839bfbd28f9890c2a6fc1cc161687c7..cd5aca961031187b1d70e4cfdc1ca16ebede6d9b 100644 (file)
@@ -21,4 +21,36 @@ defmodule Pleroma.Web.CommonAPI.Test do
 
     assert karjalanpiirakka["name"] == ":karjalanpiirakka:"
   end
+
+  describe "posting" do
+    test "it filters out obviously bad tags when accepting a post as HTML" do
+      user = insert(:user)
+
+      post = "<h1>2hu</h1><script>alert('xss')</script>"
+
+      {:ok, activity} =
+        CommonAPI.post(user, %{
+          "status" => post,
+          "content_type" => "text/html"
+        })
+
+      content = activity.data["object"]["content"]
+      assert content == "<h1>2hu</h1>alert('xss')"
+    end
+
+    test "it filters out obviously bad tags when accepting a post as Markdown" do
+      user = insert(:user)
+
+      post = "<h1>2hu</h1><script>alert('xss')</script>"
+
+      {:ok, activity} =
+        CommonAPI.post(user, %{
+          "status" => post,
+          "content_type" => "text/markdown"
+        })
+
+      content = activity.data["object"]["content"]
+      assert content == "<h1>2hu</h1>alert('xss')"
+    end
+  end
 end