From 1232cfc86a846807207fa26de81cb82bbc0d8e66 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 15 Feb 2024 21:22:41 -0700 Subject: [PATCH] Update ActivityPubFetchService, enforce stricter Content-Type validation --- app/Services/ActivityPubFetchService.php | 81 +++++++++++++++--------- 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/app/Services/ActivityPubFetchService.php b/app/Services/ActivityPubFetchService.php index cbf153ecb..4b515859c 100644 --- a/app/Services/ActivityPubFetchService.php +++ b/app/Services/ActivityPubFetchService.php @@ -11,38 +11,61 @@ use Illuminate\Http\Client\RequestException; class ActivityPubFetchService { - public static function get($url, $validateUrl = true) - { + public static function get($url, $validateUrl = true) + { if($validateUrl === true) { - if(!Helpers::validateUrl($url)) { - return 0; - } + if(!Helpers::validateUrl($url)) { + return 0; + } } - $baseHeaders = [ - 'Accept' => 'application/activity+json, application/ld+json', - ]; + $baseHeaders = [ + 'Accept' => 'application/activity+json, application/ld+json', + ]; - $headers = HttpSignature::instanceActorSign($url, false, $baseHeaders, 'get'); - $headers['Accept'] = 'application/activity+json, application/ld+json'; - $headers['User-Agent'] = 'PixelFedBot/1.0.0 (Pixelfed/'.config('pixelfed.version').'; +'.config('app.url').')'; + $headers = HttpSignature::instanceActorSign($url, false, $baseHeaders, 'get'); + $headers['Accept'] = 'application/activity+json, application/ld+json'; + $headers['User-Agent'] = 'PixelFedBot/1.0.0 (Pixelfed/'.config('pixelfed.version').'; +'.config('app.url').')'; - try { - $res = Http::withOptions(['allow_redirects' => false])->withHeaders($headers) - ->timeout(30) - ->connectTimeout(5) - ->retry(3, 500) - ->get($url); - } catch (RequestException $e) { - return; - } catch (ConnectionException $e) { - return; - } catch (Exception $e) { - return; - } - if(!$res->ok()) { - return; - } - return $res->body(); - } + try { + $res = Http::withOptions(['allow_redirects' => false]) + ->withHeaders($headers) + ->timeout(30) + ->connectTimeout(5) + ->retry(3, 500) + ->get($url); + } catch (RequestException $e) { + return; + } catch (ConnectionException $e) { + return; + } catch (Exception $e) { + return; + } + + if(!$res->ok()) { + return; + } + + if(!$res->hasHeader('Content-Type')) { + return; + } + + $acceptedTypes = [ + 'application/activity+json; charset=utf-8', + 'application/activity+json', + 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' + ]; + + $contentType = $res->getHeader('Content-Type')[0]; + + if(!$contentType) { + return; + } + + if(!in_array($contentType, $acceptedTypes)) { + return; + } + + return $res->body(); + } }