# JPKCom Harden & Trim — Anleitung & Tipps

> WordPress härten, Datenabflüsse reduzieren und Ballast abwerfen mit JPKCom Harden & Trim — Installation, unbedenkliche Standardwerte, Voreinstellungen, Konstanten in der wp-config.php und Praxis-Tipps.

Source: https://www.jpkc.com/db/guides/jpkcom-harden-trim/

JPKCom Harden & Trim bündelt gut 40 kleine Einstellungen, die eine WordPress-Site sicherer machen, weniger über sich und ihre Nutzer verraten und weniger unnötigen Code laden. Alle liegen auf einer Einstellungsseite, und jede lässt sich zusätzlich per Konstante in der `wp-config.php` festlegen. Der Grundsatz dahinter: Aktivierst du das Plugin und fasst nichts an, soll sich an deiner Site sichtbar nichts ändern — mit einer bewussten Ausnahme, XML-RPC.

## Anleitung

### Voraussetzungen

- WordPress **7.1** oder neuer (getestet bis WordPress 7.1)
- PHP **8.3** oder neuer

Die WordPress-Mindestversion liegt damit höher als bei den übrigen JPKCom-Plugins (dort 6.9 oder 7.0); PHP 8.3 verlangen sie alle.

### Installation

1. Gehe im Admin-Bereich zu **Plugins → Installieren** und klicke auf **Plugin hochladen**.
2. Wähle die ZIP-Datei des Plugins und klicke auf **Jetzt installieren**.
3. Klicke auf **Aktivieren** und sieh dir danach **Einstellungen → Harden & Trim** an.

**Wichtig direkt nach der Aktivierung:** Der Schalter **XML-RPC deaktivieren** ist ab Werk eingeschaltet. `xmlrpc.php` antwortet dann mit 403, und Jetpack, die WordPress-Apps für Mobilgeräte sowie eingehende Pingbacks und Trackbacks funktionieren nicht mehr. Brauchst du eines davon, schaltest du ihn aus oder setzt `define( 'JPKCOM_HARDEN_TRIM_XMLRPC', false );` in die `wp-config.php`.

### Die Standardwerte

Ab Werk ist nur eingeschaltet, was niemand sieht oder was Browser ohnehin tun:

- **Ballast:** Emoji-Skripte und Selbst-Pingbacks sind weg. Emoji bleiben als Unicode-Zeichen erhalten.
- **`<head>`:** Shortlink, RSD-Link, die REST-API-Links und das Generator-Tag mit der WordPress-Version verschwinden. Die REST-API selbst arbeitet weiter.
- **Datenschutz:** Die Autoren-Enumeration über `?author=N` endet für abgemeldete Besucher in einer 404 (nur mit sprechenden Permalinks), die REST-API-Benutzerliste antwortet anonymen Anfragen mit 401, oEmbed-Daten nennen die Site statt des Autors, die Benutzer verschwinden aus der Sitemap, und der Dashboard-Aufruf, der deinen Browser und deine Site-URL an api.wordpress.org meldet, entfällt.
- **Sicherheit:** Anmeldefehler sind neutral formuliert, `X-Powered-By` und `X-Redirect-By` fallen weg, `X-Content-Type-Options: nosniff` und `Referrer-Policy: strict-origin-when-cross-origin` werden gesendet, JSONP der REST-API ist aus — und XML-RPC ist gesperrt.

Abgesehen von XML-RPC ist alles, was etwas kaputt machen kann, ab Werk **aus** und trägt auf der Einstellungsseite einen Warnhinweis.

### Die Einstellungsseite

Unter **Einstellungen → Harden & Trim** sind die Schalter in fünf Gruppen sortiert: **Performance**, **`<head>` aufräumen**, **Datenschutz**, **Sicherheit** und **Rollen**. Hinweise an den einzelnen Feldern zeigen, was ein Schalter auslöst: „Verändert das Erscheinungsbild“, „Betrifft Redakteure“, „Mit Block-Themes nicht verfügbar“ oder „Durch wp-config.php gesperrt“. Welche Schalter global wirken, listet die Gruppe **Rollen** unter „Global — Rollenausnahme gilt nicht“.

Einige Schalter, die du kennen solltest, bevor du sie einschaltest:

- **Versionsangaben bei Assets:** „Durch einen Hash ersetzen“ verbirgt die Versionen im Frontend, ohne das Cache-Busting zu brechen. „Entfernen“ lässt nach Updates veraltete Dateien im Browser-Cache stehen.
- **CSS der Blockbibliothek** und **Globale Stile nicht laden:** Blockinhalte verlieren ihr Styling bzw. Farben, Abstände und Spalten-Layouts. Mit Block-Themes sind beide Schalter gesperrt.
- **Heartbeat:** „Optimiert“ setzt das Intervall auf 120 Sekunden. „Deaktiviert“ stoppt auch Beitragssperren, automatisches Speichern im klassischen Editor und das Anmelde-Fenster bei abgelaufener Sitzung.
- **IP-Adressen von Kommentierenden anonymisieren:** Neue Kommentare speichern die IP gekürzt (IPv4 auf /24, IPv6 auf /48) und keinen User-Agent. Das ist für neue Kommentare nicht umkehrbar.
- **`Strict-Transport-Security`:** Browser merken sich den Header ein Jahr lang. Schalte ihn nur ein, wenn HTTPS überall funktioniert.
- **Anwendungspasswörter:** „Für alle deaktiviert“ oder „Nur für die unten ausgewählten Rollen“. Ohne sie funktionieren MCP- und Abilities-Clients, die Mobil-App und andere Integrationen nicht mehr. Wählst du die Rollen-Variante ohne eine Rolle, kann niemand sie nutzen, auch Administratoren nicht.
- **Kommentare deaktivieren:** Verhält sich wie [JPKCom Disable Comments](https://www.jpkc.com/db/guides/jpkcom-disable-comments/) in Version 1.0.11 — Kommentare zu, vorhandene ausgeblendet (nicht gelöscht), Kommentar-Feeds und REST-Routen mit 404. Die Anmerkungen im Block-Editor funktionieren weiter. Der Schalter ist nie Teil einer Voreinstellung.

### Voreinstellungen

Drei Voreinstellungen setzen eine ganze Gruppe von Schaltern auf einmal:

| Voreinstellung | Inhalt |
|---|---|
| **Unbedenklich** | die Standardwerte, XML-RPC gesperrt |
| **Empfohlen** | zusätzlich optimierter Heartbeat, `X-Frame-Options`, kein Widget „Veranstaltungen und Neuigkeiten“, datenschutzfreundliche Video-Einbettungen, Datei-Editoren aus, 20 Revisionen |
| **Streng** | zusätzlich gehashte Asset-Versionen, keine Beitragseinbettungen, kein Kommentar-Antwortskript, keine Dashicons für Besucher, lokale Avatare, gekürzte Kommentar-IPs, Editor ohne externe Inhalte, KI-Funktionen aus, `Permissions-Policy`, 5 Revisionen, 2 Minuten Autosave |

Eine Voreinstellung setzt jeden Schalter, den sie verwaltet, auf ihren eigenen Wert oder den Standardwert, fasst keinen gesperrten Schalter an und schaltet nie einen der riskanten ein. Ein deaktivierter Heartbeat oder entfernte Asset-Versionen werden dabei also zurückgesetzt. Nie angefasst werden: Kommentare deaktivieren, CSS der Blockbibliothek, globale Stile, HSTS, Feed-Links, Anwendungspasswörter und die Rollenlisten. Vor dem Anwenden fragt die Seite nach und listet danach die geänderten Schalter auf.

### Konstanten in der wp-config.php

Jeder Schalter hat eine Konstante. Sie gewinnt immer gegen den gespeicherten Wert und sperrt das Feld auf der Einstellungsseite. Setze sie vor die Zeile „That's all, stop editing“:

```php
define( 'JPKCOM_HARDEN_TRIM_EMOJI', true );
define( 'JPKCOM_HARDEN_TRIM_HEARTBEAT', 'optimized' );
define( 'JPKCOM_HARDEN_TRIM_POST_REVISIONS', 20 );
define( 'JPKCOM_HARDEN_TRIM_EXEMPT_ROLES', 'editor,author' );
```

Schalter nehmen `true` oder `false`, Auswahlfelder einen exakten Wert wie `optimized`, Zahlenfelder einen Wert aus der Auswahlliste (etwa `20`, nicht `7`), Rollenlisten ein Array oder eine kommagetrennte Liste. Einen ungültigen Wert ignoriert das Plugin und nennt die Konstante auf der Einstellungsseite. Die WordPress-eigenen Konstanten `WP_POST_REVISIONS`, `AUTOSAVE_INTERVAL`, `DISALLOW_FILE_EDIT` und `WP_AI_SUPPORT` haben wiederum Vorrang vor dem Plugin und seinen Konstanten.

### Rollenausnahme

Unter **Rollen** wählst du Rollen, die das unveränderte WordPress sehen. Das gilt nur für sechs Schalter, die angemeldete Nutzer direkt betreffen: Emoji, Asset-Versionen, Kommentar-Antwortskript, CSS der Blockbibliothek, globale Stile und Heartbeat. Alles andere wirkt global. Auf Multisite zählt ein Super-Admin auf jeder Site als Administrator. Ab Werk ist keine Rolle ausgenommen.

### Import, Export und Notschalter

**Export** lädt die gespeicherten Einstellungen als JSON-Datei herunter — ohne Site-URL und ohne Nutzerdaten. **Import** nimmt eine Datei bis 64 KB oder eingefügtes JSON an, akzeptiert nur bekannte Schlüssel, prüft jeden Wert wie das Formular und meldet, wie viele Einstellungen übernommen und welche abgelehnt wurden. Das ist der einfachste Weg, dieselbe Konfiguration auf mehrere Sites zu bringen.

Geht nach einer Änderung etwas kaputt, schaltet `define( 'JPKCOM_HARDEN_TRIM_DISABLE_ALL', true );` in der `wp-config.php` alle Funktionen ab. Die Einstellungsseite bleibt erreichbar und zeigt einen Hinweis. Das Deaktivieren des Plugins wirkt genauso.

## Tipps & Tricks

- **Jeden Schalter nur an einer Stelle:** SEO-, Caching- und Sicherheits-Plugins bieten oft dieselben Funktionen. Bei Headern gilt das besonders: Das Plugin überspringt einen Header, den WordPress oder ein anderes Plugin schon in PHP gesetzt hat, sieht aber keine Header aus der Server-Konfiguration (nginx `add_header`, Apache `mod_headers`), einem Proxy oder einem CDN. Doppelte `Strict-Transport-Security`-Header sind der schlimmste Fall. Liefert ein Seiten-Cache die Seiten aus, fehlen PHP-Header womöglich ganz — dann ist die Server-Konfiguration der verlässlichere Ort.
- **XML-RPC dauerhaft offen lassen:** Jede Voreinstellung schaltet XML-RPC wieder **ein**, auch wenn du es vorher für Jetpack ausgeschaltet hattest. Mit `define( 'JPKCOM_HARDEN_TRIM_XMLRPC', false );` bleibt es offen, egal welche Voreinstellung du anwendest.
- **Neben den Einzel-Plugins:** Die Schalter für XML-RPC und Kommentare verhalten sich Hook für Hook wie [JPKCom Disable XML-RPC](https://www.jpkc.com/db/guides/jpkcom-disable-xmlrpc/) und JPKCom Disable Comments. Beide Einzel-Plugins werden weiter gepflegt, und sie parallel zu betreiben schadet nicht; die Einstellungsseite weist darauf hin. Einzige Ausnahme: JPKCom Disable Comments bis 1.0.10 entfernt die REST-Routen für Kommentare und legt damit die Anmerkungen im Block-Editor lahm, auch neben diesem Plugin. Aktualisiere es mindestens auf 1.0.11. Die Login-URL zu verstecken, bleibt Sache von [JPKCom Hide Login](https://www.jpkc.com/db/guides/jpkcom-hide-login/).
- **Autoren-Enumeration und ActivityPub:** Nutzt du das ActivityPub-Plugin, lässt der Schalter nur die Anfragen durch, die ActivityPub selbst mit dem Actor-Dokument beantwortet. Die Föderation findet deine Autoren also weiter, jede andere `?author=N`-Anfrage bekommt die 404.
- **Kein DSGVO-Werkzeug:** Die Datenschutz-Schalter verringern, was deine Site an Dritte sendet und über ihre Nutzer preisgibt. Datenschutzerklärung, Einwilligungs-Tool, Auftragsverarbeitungsvertrag oder Rechtsberatung ersetzen sie nicht — auch die datenschutzfreundlichen Video-Einbettungen sind keine Einwilligungslösung.
- **Einstellungs-Filter in ein Plugin:** Der Filter `jpkcom_harden_trim_settings` läuft genau einmal, beim Hook `plugins_loaded`. In der `functions.php` eines Themes kommt er zu spät — leg ihn in ein (MU-)Plugin.
- **Deaktivieren oder löschen:** Beim Deaktivieren bleiben die Einstellungen erhalten. Erst das Löschen entfernt die gespeicherte Option und die zwischengespeicherten Daten, auf Multisite auf jeder Site.
- **Das Plugin selbst ist still:** keine externen Anfragen, keine Telemetrie. Einzige Ausnahme ist der Updater, der ein Manifest von GitHub Pages lädt und es einen Tag lang zwischenspeichert. Der Header `Update URI` ist von Anfang an gesetzt, die Update-Schnittstelle von wordpress.org liefert für dieses Plugin also keine Updates — ein dort veröffentlichtes Plugin mit demselben Slug kann sich nicht als Update ausgeben.

## Weiterführende Informationen

- Quellcode auf GitHub: <https://github.com/JPKCom/jpkcom-harden-trim>
- API-Dokumentation (PHPDoc): <https://jpkcom.github.io/jpkcom-harden-trim/docs/>
- [Changelog dieses Projekts](https://www.jpkc.com/db/changelog/jpkcom-harden-trim/)
- Verwandte Plugins: [JPKCom Disable Comments](https://www.jpkc.com/db/guides/jpkcom-disable-comments/), [JPKCom Disable XML-RPC](https://www.jpkc.com/db/guides/jpkcom-disable-xmlrpc/), [JPKCom Hide Login](https://www.jpkc.com/db/guides/jpkcom-hide-login/)

