activitypub: verify remote http signature digests by recomputing the digest and repla...
authorWilliam Pitcock <nenolod@dereferenced.org>
Tue, 31 Jul 2018 23:17:47 +0000 (23:17 +0000)
committerWilliam Pitcock <nenolod@dereferenced.org>
Tue, 31 Jul 2018 23:24:30 +0000 (23:24 +0000)
lib/pleroma/plugs/digest.ex [new file with mode: 0644]
lib/pleroma/plugs/http_signature.ex
lib/pleroma/web/endpoint.ex

diff --git a/lib/pleroma/plugs/digest.ex b/lib/pleroma/plugs/digest.ex
new file mode 100644 (file)
index 0000000..9d6bbb0
--- /dev/null
@@ -0,0 +1,10 @@
+defmodule Pleroma.Web.Plugs.DigestPlug do
+  alias Plug.Conn
+  require Logger
+
+  def read_body(conn, opts) do
+    {:ok, body, conn} = Conn.read_body(conn, opts)
+    digest = "SHA-256=" <> (:crypto.hash(:sha256, body) |> Base.encode64())
+    {:ok, body, Conn.assign(conn, :digest, digest)}
+  end
+end
index 38bcd3a782d688d3748e710bd3de912206cff64d..9e53371b74664baa54a8bede27db3079fa1e406d 100644 (file)
@@ -19,6 +19,8 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
 
     cond do
       signature && String.contains?(signature, user) ->
+        # set (request-target) header to the appropriate value
+        # we also replace the digest header with the one we computed
         conn =
           conn
           |> put_req_header(
@@ -26,6 +28,14 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
             String.downcase("#{conn.method}") <> " #{conn.request_path}"
           )
 
+        conn =
+          if conn.assigns[:digest] do
+            conn
+            |> put_req_header("digest", conn.assigns[:digest])
+          else
+            conn
+          end
+
         assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn))
 
       signature ->
index 1a012c1b416a05c5e6743cf2f0792af0045042e4..cbedca0046333196030b838363640e4be1c139d0 100644 (file)
@@ -35,7 +35,8 @@ defmodule Pleroma.Web.Endpoint do
     parsers: [:urlencoded, :multipart, :json],
     pass: ["*/*"],
     json_decoder: Jason,
-    length: Application.get_env(:pleroma, :instance) |> Keyword.get(:upload_limit)
+    length: Application.get_env(:pleroma, :instance) |> Keyword.get(:upload_limit),
+    body_reader: {Pleroma.Web.Plugs.DigestPlug, :read_body, []}
   )
 
   plug(Plug.MethodOverride)