From 3caab0d808c7ef9fe9ef03c88f6b6835bad961c5 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 26 Apr 2020 22:25:43 -0400 Subject: [PATCH] Sanitize incoming HTML --- lib/clacks/inbox.ex | 22 ++++++++-------------- lib/clacks/inbox/transformer.ex | 17 +++++++++++++++++ mix.exs | 3 ++- mix.lock | 2 ++ 4 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 lib/clacks/inbox/transformer.ex diff --git a/lib/clacks/inbox.ex b/lib/clacks/inbox.ex index a85272c..6aaca3b 100644 --- a/lib/clacks/inbox.ex +++ b/lib/clacks/inbox.ex @@ -17,22 +17,16 @@ defmodule Clacks.Inbox do @spec handle(activity :: map()) :: :ok | {:error, reason :: any()} def handle(%{"type" => "Create", "object" => object} = activity) do - changeset = Object.changeset(%Object{}, %{data: object}) + object = Clacks.Inbox.Transformer.restrict_incoming_object(object) + changeset = Object.changeset_for_creating(object) - case Repo.insert(changeset) do + with {:ok, _object} <- Repo.insert(changeset), + {:ok, _activity} <- store_activity(activity) do + :ok + else {:error, changeset} -> - Logger.error("Couldn't store object: #{inspect(changeset)}") - {:error, "Couldn't store changeset"} - - {:ok, _object} -> - case store_activity(activity) do - {:error, changeset} -> - Logger.error("Couldn't store Create activity: #{inspect(changeset)}") - {:error, "Couldn't store Create activity"} - - {:ok, _activity} -> - :ok - end + Logger.error("Couldn't store object or activity: #{inspect(changeset)}") + {:error, "Couldn't store activity"} end end diff --git a/lib/clacks/inbox/transformer.ex b/lib/clacks/inbox/transformer.ex new file mode 100644 index 0000000..26bd857 --- /dev/null +++ b/lib/clacks/inbox/transformer.ex @@ -0,0 +1,17 @@ +defmodule Clacks.Inbox.Transformer do + @spec restrict_incoming_object(object :: map()) :: map() + def restrict_incoming_object(%{"content" => content} = object) do + content = sanitize_html(content) + %{object | "content" => content} + end + + def restrict_incoming_object(object) do + object + end + + @spec sanitize_html(content :: String.t()) :: String.t() + defp sanitize_html(content) do + {:ok, res} = FastSanitize.basic_html(content) + res + end +end diff --git a/mix.exs b/mix.exs index 13a2d3d..1da63b9 100644 --- a/mix.exs +++ b/mix.exs @@ -50,7 +50,8 @@ defmodule Clacks.MixProject do {:httpoison, "~> 1.5.1"}, {:timex, "~> 3.6.1"}, {:bcrypt_elixir, "~> 2.0"}, - {:oban, "~> 1.2.0"} + {:oban, "~> 1.2.0"}, + {:fast_sanitize, "~> 0.1.7"} ] end diff --git a/mix.lock b/mix.lock index c251070..d4a8547 100644 --- a/mix.lock +++ b/mix.lock @@ -13,6 +13,8 @@ "ecto": {:hex, :ecto, "3.2.1", "a0f9af0fb50b19d3bb6237e512ac0ba56ea222c2bbea92e7c6c94897932c76ba", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "e1a1a1d72514b880d6bdd9fe9423d13a800ec1fb041c7239d885e5407b1fabce"}, "ecto_sql": {:hex, :ecto_sql, "3.2.0", "751cea597e8deb616084894dd75cbabfdbe7255ff01e8c058ca13f0353a3921b", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.2.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.2.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a2e23cf761668126252418cae07eff7967ad0152fbc5e2d0dc3de487a5ec774c"}, "elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm", "d522695b93b7f0b4c0fcb2dfe73a6b905b1c301226a5a55cb42e5b14d509e050"}, + "fast_html": {:hex, :fast_html, "1.0.3", "2cc0d4b68496266a1530e0c852cafeaede0bd10cfdee26fda50dc696c203162f", [:make, :mix], [], "hexpm", "ab3d782b639d3c4655fbaec0f9d032c91f8cab8dd791ac7469c2381bc7c32f85"}, + "fast_sanitize": {:hex, :fast_sanitize, "0.1.7", "2a7cd8734c88a2de6de55022104f8a3b87f1fdbe8bbf131d9049764b53d50d0d", [:mix], [{:fast_html, "~> 1.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f39fe8ea08fbac17487c30bf09b7d9f3e12472e51fb07a88ffeb8fd17da8ab67"}, "file_system": {:hex, :file_system, "0.2.7", "e6f7f155970975789f26e77b8b8d8ab084c59844d8ecfaf58cbda31c494d14aa", [:mix], [], "hexpm", "b4cfa2d69c7f0b18fd06db222b2398abeef743a72504e6bd7df9c52f171b047f"}, "flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"}, "gettext": {:hex, :gettext, "0.17.0", "abe21542c831887a2b16f4c94556db9c421ab301aee417b7c4fbde7fbdbe01ec", [:mix], [], "hexpm", "e0b8598e802676c81e66b061a2148c37c03886b24a3ca86a1f98ed40693b94b3"},