logo

Extra Block Types (EBT) - Neue Erfahrung im Layout Builder❗

Extra Block Types (EBT) - gestylte, anpassbare Blocktypen: Diashows, Registerkarten, Karten, Akkordeons und viele andere. Eingebaute Einstellungen für Hintergrund, DOM Box, Javascript Plugins. Erleben Sie die Zukunft der Layouterstellung schon heute.

Demo EBT-Module EBT-Module herunterladen

❗Extra Absatztypen (EPT) - Erfahrung mit neuen Absätzen

Extra Paragraph Types (EPT) - analoger, auf Absätzen basierender Satz von Modulen.

Demo EPT-Module EPT-Module herunterladen

Scroll
21/05/2025, by Ivan

Das JSON:API-Modul wurde entwickelt, um das in Drupal über die Entity API, Field API und Typed Data API definierte Datenmodell über eine API bereitzustellen, die der JSON:API-Spezifikation entspricht. Damit wird die Interaktion mit den von Drupal verwalteten Daten (Entities) erleichtert.

Dabei werden alle Drupal-Sicherheitsmechanismen für diese Daten beachtet:

  • Der Zugriff auf Entitäten wird respektiert.
  • Der Zugriff auf Felder wird respektiert.
  • Beim Ändern von Daten werden Validierungsregeln eingehalten.
  • Das internal-Flag wird beachtet (siehe Dokumentation, wie es auf eine Entity-, Feld- oder Property-Definition gesetzt werden kann).

Mit anderen Worten: JSON:API umgeht keine bestehenden Sicherheitsmechanismen und fügt auch keine eigene Sicherheitsschicht hinzu; es nutzt die Drupal-Basis vollständig aus.

Fehler in Entity-Typen, Feldtypen und Datentypen können zu Sicherheitslücken führen

Trotzdem gibt es Fehler in der Implementierung von Entity-Typen, Feldtypen und Datentypen sowie in deren Access-Control-Handlern und Validierungsregeln. Das liegt vor allem an Drupals Historie: Früher gab es keine Validierungsregeln, sondern nur Formular-Validierungen; der Wechsel zu einer API-First-Architektur ist im Drupal-Core vollzogen, aber bei Contrib- oder eigenen Modulen nicht garantiert.

Solche Fehler können zu Sicherheitslücken führen – und haben das in der Vergangenheit auch. Diese Lücken betreffen nicht nur das JSON:API-Modul, sondern z.B. auch das RESTful Web Services-Modul oder beliebigen PHP-Code, der die Entity API verwendet.

Da ein Angreifer aber viel leichter auf eine HTTP-API wie JSON:API oder RESTful Web Services zugreifen kann als auf eine PHP-API, ist hier besondere Vorsicht geboten. Im Gegensatz zu anderen HTTP-API-Modulen ist die API-Oberfläche von JSON:API größer: Alle nicht-internal-Entity-Typen sind standardmäßig verfügbar (wobei Entity Access beachtet wird), um das Entwicklererlebnis zu verbessern.

Sechs Sicherheitshinweise

1. Die Bedeutung stabiler Contributed Modules

Sicherheitslücken in Entity-Typen, Feldtypen und Datentypen werden nur für stabile, auf Drupal.org veröffentlichte Module, die unter die Security Advisory Policy fallen, schnell behoben. Eigene Module und nicht-stabile Contributed Modules sind nicht abgedeckt. Bei deren Einsatz ist besondere Vorsicht geboten.

2. Überprüfe Entity- und Feldzugriffsrechte

Unabhängig davon, ob du JSON:API oder andere API-Module nutzt, solltest du den Entity Access & Field Access auf Drupal-Sites auditieren. Das ist besonders wichtig, wenn die Schreibfunktion von JSON:API aktiviert ist.

3. Exponiere nur, was du wirklich brauchst

Wenn bestimmte Ressourcentypen (Entity-Typ + Bundle) nicht zugänglich sein sollen, kann man – nachdem der Zugriff verweigert wurde – noch weitergehen und sie komplett deaktivieren. Dies geht per PHP-API im eigenen Modul oder über das JSON:API Extras Modul, das eine UI dafür bietet. Das ist nicht immer möglich, aber wenn der Site-Owner auch alle API-Clients kontrolliert, kann man so die API-Oberfläche so klein wie möglich halten.

4. Nur-Lese-Modus

Falls du nur Lesezugriff brauchst, kannst du im JSON:API-Modul unter /admin/config/services/jsonapi den Nur-Lese-Modus aktivieren. Dadurch werden Risiken durch potentielle Bugs in Validierungsregeln und Write-Logik reduziert. Da viele moderne decoupled Drupal-Setups ohnehin nur Lesezugriff benötigen, ist der Nur-Lese-Modus standardmäßig aktiviert (in Drupal Core und seit Version 2.4 des Contributed-Moduls).

5. Sicherheit durch Verschleierung: Geheimer Basis-Pfad

Standardmäßig ist der Basis-Pfad für JSON:API /jsonapi. Dies kann auf z.B. /hidden/b69dhj027ooae/jsonapi geändert werden, um automatisierte Angriffe zu erschweren. Erstelle sites/example.com/services.yml (sofern nicht vorhanden) und füge hinzu:

parameters:
  jsonapi.base_path: /hidden/b69dhj027ooae/jsonapi

6. Begrenze, welche Entity-Bundles erstellt/editiert werden dürfen (durch Entfernen von Routen)

Wenn du nur bestimmte Entity-Bundles per JSON:API erstellen oder bearbeiten lassen willst, kannst du einen Event-Subscriber in einem eigenen Modul schreiben, der nur eine Whitelist von POST- und PATCH-Routen zulässt. Dies wirkt sich nach Deaktivierung des Nur-Lese-Modus aus und erfordert ggf. einen Router-Rebuild.

Füge in der services.yml deines Moduls Folgendes hinzu:

services:
  mymodule.route_subscriber:
    class: Drupal\mymodule\Routing\JsonapiLimitingRouteSubscriber
    tags:
      - { name: event_subscriber }

Beispiel für einen Event Subscriber (löscht auch alle DELETE-Routen):

<?php

namespace Drupal\mymodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Klasse JsonapiLimitingRouteSubscriber.
 *
 * Entfernt alle DELETE-Routen von JSON:API-Resourcen zum Schutz von Inhalten.
 * Entfernt POST- und PATCH-Routen von JSON:API-Resourcen, außer für die,
 * die von Endbenutzern via API erstellt/geändert werden dürfen.
 */
class JsonapiLimitingRouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    $mutable_types = $this->mutableResourceTypes();
    foreach ($collection as $name => $route) {
      $defaults = $route->getDefaults();
      if (!empty($defaults['_is_jsonapi']) && !empty($defaults['resource_type'])) {
        $methods = $route->getMethods();
        if (in_array('DELETE', $methods)) {
          // Löschen nie erlauben, nur deaktivieren.
          $collection->remove($name);
        }
        else {
          $resource_type = $defaults['resource_type'];
          if (empty($mutable_types[$resource_type])) {
            if (in_array('POST', $methods) || in_array('PATCH', $methods)) {
              $collection->remove($name);
            }
          }
        }
      }
    }
  }

  /**
   * Gibt veränderbare Resourcentypen zurück, die via API bearbeitet werden dürfen.
   *
   * @return array
   *   Liste der JSON:API-Resourcentypen (als Schlüssel).
   */
  public function mutableResourceTypes(): array {
    return [
      'node--article' => TRUE,
      'node--document' => TRUE,
      'custom_entity--custom_entity' => TRUE,
    ];
  }

}

Zugriff auf alle JSON:API-Routen mit zusätzlicher Berechtigung einschränken

Wenn du JSON:API für Backend-Integrationen, eingeschränkte API-Clients oder andere nicht-öffentliche Einsätze nutzt, kann es sinnvoll sein, den Zugriff auf alle JSON:API-Endpunkte an eine spezielle Berechtigung zu knüpfen. Ergänze dazu den Route Subscriber wie folgt:

    // Zugriff auf alle jsonapi-Routen über ein extra Recht begrenzen.
    foreach ($collection as $route) {
      $defaults = $route->getDefaults();
      if (!empty($defaults['_is_jsonapi'])) {
        $route->setRequirement('_permission', 'FOO custom access jsonapi');
      }
    }

Lege diese Berechtigung in FOO.permissions.yml an und weise sie den gewünschten Rollen zu.

Artikel aus der Drupal Dokumentation.