From 73a7df85f7bbbb8fd5c31626ab91c58b1e31e4a2 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 2 Oct 2020 09:31:39 +0000 Subject: [PATCH] Issue 9303: Detect AP accesses as backend, prevent ping pong --- src/App.php | 4 ++-- src/App/Mode.php | 11 +++++++++-- src/Model/APContact.php | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/App.php b/src/App.php index 91a5a07446..adb4e55ae7 100644 --- a/src/App.php +++ b/src/App.php @@ -448,7 +448,7 @@ class App Core\Worker::executeIfIdle(); } - if ($this->mode->isNormal()) { + if ($this->mode->isNormal() && !$this->mode->isBackend()) { $requester = HTTPSignature::getSigner('', $_SERVER); if (!empty($requester)) { Profile::addVisitorCookieForHandle($requester); @@ -456,7 +456,7 @@ class App } // ZRL - if (!empty($_GET['zrl']) && $this->mode->isNormal()) { + if (!empty($_GET['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend()) { if (!local_user()) { // Only continue when the given profile link seems valid // Valid profile links contain a path with "/profile/" and no query parameters diff --git a/src/App/Mode.php b/src/App/Mode.php index cc18373e9e..79d6d87ffa 100644 --- a/src/App/Mode.php +++ b/src/App/Mode.php @@ -134,8 +134,15 @@ class Mode */ public function determineRunMode(bool $isBackend, Module $module, array $server, MobileDetect $mobileDetect) { - $isBackend = $isBackend || - $module->isBackend(); + $contenttypes = ['application/jrd+json', 'application/xrd+xml', 'text/xml', + 'application/rss+xml', 'application/atom+xml', 'application/activity+json']; + foreach ($contenttypes as $type) { + if (strpos(strtolower($server['HTTP_ACCEPT'] ?? ''), $type) !== false) { + $isBackend = true; + } + } + + $isBackend = $isBackend || $module->isBackend(); $isMobile = $mobileDetect->isMobile(); $isTablet = $mobileDetect->isTablet(); $isAjax = strtolower($server['HTTP_X_REQUESTED_WITH'] ?? '') == 'xmlhttprequest'; diff --git a/src/Model/APContact.php b/src/Model/APContact.php index d31aa5d372..6a8e5b3ae1 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -22,8 +22,11 @@ namespace Friendica\Model; use Friendica\Content\Text\HTML; +use Friendica\Core\Cache\Duration; use Friendica\Core\Logger; +use Friendica\Core\System; use Friendica\Database\DBA; +use Friendica\DI; use Friendica\Network\Probe; use Friendica\Protocol\ActivityNamespace; use Friendica\Protocol\ActivityPub; @@ -40,7 +43,7 @@ class APContact * @param string $addr Address * @return array webfinger data */ - public static function fetchWebfingerData(string $addr) + private static function fetchWebfingerData(string $addr) { $addr_parts = explode('@', $addr); if (count($addr_parts) != 2) { @@ -154,6 +157,16 @@ class APContact return $fetched_contact; } + // Detect multiple fast repeating request to the same address + // See https://github.com/friendica/friendica/issues/9303 + $cachekey = 'apcontact:getByURL:' . $url; + $result = DI::cache()->get($cachekey); + if (!is_null($result)) { + Logger::notice('Multiple requests for the address', ['url' => $url, 'update' => $update, 'callstack' => System::callstack(20), 'result' => $result]); + } else { + DI::cache()->set($cachekey, System::callstack(20), Duration::FIVE_MINUTES); + } + $apcontact['url'] = $compacted['@id']; $apcontact['uuid'] = JsonLD::fetchElement($compacted, 'diaspora:guid', '@value'); $apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type'));