From 5265df0a8a9d66a88cbb45bff5e9316a357e934a Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Mon, 3 Feb 2020 17:48:23 +0100
Subject: [PATCH] Change signature verification to ignore signatures with
 invalid host (#13033)

Instead of returning a signature verification error, pretend there
was no signature (i.e., this does not allow access to resources that
need a valid signature), so public resources can still be fetched

Fix #13011
---
 .../concerns/signature_verification.rb        |  2 ++
 .../concerns/signature_verification_spec.rb   | 27 +++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index ce353f1de..10efbf2e0 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -160,6 +160,8 @@ module SignatureVerification
       account ||= stoplight_wrap_request { ActivityPub::FetchRemoteKeyService.new.call(key_id, id: false) }
       account
     end
+  rescue Mastodon::HostValidationError
+    nil
   end
 
   def stoplight_wrap_request(&block)
diff --git a/spec/controllers/concerns/signature_verification_spec.rb b/spec/controllers/concerns/signature_verification_spec.rb
index 1fa19f54d..05fb1445b 100644
--- a/spec/controllers/concerns/signature_verification_spec.rb
+++ b/spec/controllers/concerns/signature_verification_spec.rb
@@ -97,6 +97,33 @@ describe ApplicationController, type: :controller do
       end
     end
 
+    context 'with inaccessible key' do
+      before do
+        get :success
+
+        author = Fabricate(:account, domain: 'localhost:5000', uri: 'http://localhost:5000/actor')
+        fake_request = Request.new(:get, request.url)
+        fake_request.on_behalf_of(author)
+        author.destroy
+
+        request.headers.merge!(fake_request.headers)
+
+        stub_request(:get, 'http://localhost:5000/actor#main-key').to_raise(Mastodon::HostValidationError)
+      end
+
+      describe '#signed_request?' do
+        it 'returns true' do
+          expect(controller.signed_request?).to be true
+        end
+      end
+
+      describe '#signed_request_account' do
+        it 'returns nil' do
+          expect(controller.signed_request_account).to be_nil
+        end
+      end
+    end
+
     context 'with body' do
       before do
         post :success, body: 'Hello world'