Procházet zdrojové kódy

add nosniff header to all JSON responses and escape base path in JSON-LD response

El RIDO před 3 týdny
rodič
revize
b4e162ac23
4 změnil soubory, kde provedl 29 přidání a 7 odebrání
  1. 2 0
      CHANGELOG.md
  2. 3 1
      lib/Controller.php
  3. 23 5
      tst/JsonApiTest.php
  4. 1 1
      tst/RequestTest.php

+ 2 - 0
CHANGELOG.md

@@ -4,6 +4,8 @@
 * CHANGED: Upgrading libraries to: DOMpurify 3.4.12
 * FIXED: Gracefully handle YOURLS replies with a 200 status code but no shorturl, instead of raising a TypeError
 * FIXED: Return "Invalid data." instead of HTTP 500 on malformed v2 JSON payloads (#1883)
+* FIXED: Prevent browsers guessing MIME types on JSON(LD) API responses (#164)
+* FIXED: Insert quoted base path into JSON-LD documents
 
 ## 2.0.5 (2026-07-11)
 * CHANGED: Show OS-specific copy hotkey hint (Cmd+c on Mac, Ctrl+c on others) (#1506)

+ 3 - 1
lib/Controller.php

@@ -169,6 +169,7 @@ class Controller
             header('Access-Control-Allow-Origin: *');
             header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
             header('Access-Control-Allow-Headers: X-Requested-With, Content-Type');
+            header('X-Content-Type-Options: nosniff');
             header('X-Uncompressed-Content-Length: ' . strlen($this->_json));
             header('Access-Control-Expose-Headers: X-Uncompressed-Content-Length');
             echo $this->_json;
@@ -514,7 +515,7 @@ class Controller
         if (is_readable($file)) {
             $content = str_replace(
                 '?jsonld=',
-                $this->_urlBase . '?jsonld=',
+                trim(Json::encode($this->_urlBase), '"') . '?jsonld=',
                 file_get_contents($file)
             );
         }
@@ -529,6 +530,7 @@ class Controller
         header('Content-type: application/ld+json');
         header('Access-Control-Allow-Origin: *');
         header('Access-Control-Allow-Methods: GET');
+        header('X-Content-Type-Options: nosniff');
         echo $content;
     }
 

+ 23 - 5
tst/JsonApiTest.php

@@ -199,7 +199,7 @@ class JsonApiTest extends TestCase
         ob_end_clean();
         $this->assertEquals(str_replace(
             '?jsonld=',
-            '/?jsonld=',
+            '\/?jsonld=',
             file_get_contents(PUBLIC_PATH . '/js/paste.jsonld')
         ), $content, 'outputs data correctly');
     }
@@ -216,7 +216,7 @@ class JsonApiTest extends TestCase
         ob_end_clean();
         $this->assertEquals(str_replace(
             '?jsonld=',
-            '/?jsonld=',
+            '\/?jsonld=',
             file_get_contents(PUBLIC_PATH . '/js/comment.jsonld')
         ), $content, 'outputs data correctly');
     }
@@ -233,7 +233,7 @@ class JsonApiTest extends TestCase
         ob_end_clean();
         $this->assertEquals(str_replace(
             '?jsonld=',
-            '/?jsonld=',
+            '\/?jsonld=',
             file_get_contents(PUBLIC_PATH . '/js/pastemeta.jsonld')
         ), $content, 'outputs data correctly');
     }
@@ -250,7 +250,7 @@ class JsonApiTest extends TestCase
         ob_end_clean();
         $this->assertEquals(str_replace(
             '?jsonld=',
-            '/?jsonld=',
+            '\/?jsonld=',
             file_get_contents(PUBLIC_PATH . '/js/commentmeta.jsonld')
         ), $content, 'outputs data correctly');
     }
@@ -267,11 +267,29 @@ class JsonApiTest extends TestCase
         ob_end_clean();
         $this->assertEquals(str_replace(
             '?jsonld=',
-            '/?jsonld=',
+            '\/?jsonld=',
             file_get_contents(PUBLIC_PATH . '/js/types.jsonld')
         ), $content, 'outputs data correctly');
     }
 
+    /**
+     * @runInSeparateProcess
+     */
+    public function testJsonLdPathBypass()
+    {
+        $_SERVER['REQUEST_URI']    = '/","bypass\\';
+        $_GET['jsonld'] = 'paste';
+        ob_start();
+        new Controller;
+        $content = ob_get_contents();
+        ob_end_clean();
+        $this->assertEquals(str_replace(
+            '?jsonld=',
+            '\/\",\"bypass\\\\?jsonld=',
+            file_get_contents(PUBLIC_PATH . '/js/paste.jsonld')
+        ), $content, 'outputs data correctly');
+    }
+
     /**
      * @runInSeparateProcess
      */

+ 1 - 1
tst/RequestTest.php

@@ -20,7 +20,7 @@ class RequestTest extends TestCase
      */
     public function getRandomQueryChars()
     {
-        $queryChars     = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=';
+        $queryChars     = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=-_.!~*()';
         $queryCharCount = strlen($queryChars) - 1;
         $resultLength   = random_int(1, 10);
         $result         = '';