Merge pull request #9915 from MrPetovan/bug/9895-twitter-oembed
authorTobias Diekershoff <tobias.diekershoff@gmx.net>
Wed, 10 Feb 2021 10:31:42 +0000 (11:31 +0100)
committerGitHub <noreply@github.com>
Wed, 10 Feb 2021 10:31:42 +0000 (11:31 +0100)
Harden OEmbed link discovery

src/Content/OEmbed.php

index 355dda3..1a5d1d9 100644 (file)
@@ -98,21 +98,23 @@ class OEmbed
                                // try oembed autodiscovery
                                $html_text = DI::httpRequest()->fetch($embedurl, 15, 'text/*');
                                if ($html_text) {
-                                       $dom = @DOMDocument::loadHTML($html_text);
-                                       if ($dom) {
+                                       $dom = new DOMDocument();
+                                       if ($dom->loadHTML($html_text)) {
                                                $xpath = new DOMXPath($dom);
-                                               $entries = $xpath->query("//link[@type='application/json+oembed']");
-                                               foreach ($entries as $e) {
-                                                       $href = $e->getAttributeNode('href')->nodeValue;
-                                                       $json_string = DI::httpRequest()->fetch($href . '&maxwidth=' . $a->videowidth);
-                                                       break;
-                                               }
-
-                                               $entries = $xpath->query("//link[@type='text/json+oembed']");
-                                               foreach ($entries as $e) {
-                                                       $href = $e->getAttributeNode('href')->nodeValue;
-                                                       $json_string = DI::httpRequest()->fetch($href . '&maxwidth=' . $a->videowidth);
-                                                       break;
+                                               foreach (
+                                                       $xpath->query("//link[@type='application/json+oembed'] | //link[@type='text/json+oembed']")
+                                                       as $link)
+                                               {
+                                                       $href = $link->getAttributeNode('href')->nodeValue;
+                                                       // Both Youtube and Vimeo output OEmbed endpoint URL with HTTP
+                                                       // but their OEmbed endpoint is only accessible by HTTPS ¯\_(ツ)_/¯
+                                                       $href = str_replace(['http://www.youtube.com/', 'http://player.vimeo.com/'],
+                                                               ['https://www.youtube.com/', 'https://player.vimeo.com/'], $href);
+                                                       $result = DI::httpRequest()->fetchFull($href . '&maxwidth=' . $a->videowidth);
+                                                       if ($result->getReturnCode() === 200) {
+                                                               $json_string = $result->getBody();
+                                                               break;
+                                                       }
                                                }
                                        }
                                }
@@ -337,10 +339,6 @@ class OEmbed
 
        public static function getHTML($url, $title = null)
        {
-               // Always embed the SSL version
-               $url = str_replace(["http://www.youtube.com/", "http://player.vimeo.com/"],
-                                       ["https://www.youtube.com/", "https://player.vimeo.com/"], $url);
-
                $o = self::fetchURL($url, !self::isAllowedURL($url));
 
                if (!is_object($o) || property_exists($o, 'type') && $o->type == 'error') {