RAIVN Botban

Diese WordPress Sicherheits-Schutzregeln brauchst du unbedingt

functions.php

Diese 5 wichtige Sicherheits-Schutzregeln, die in der functions.php deiner WordPress-Seite nicht fehlen sollten, um grundlegende Schwachstellen zu mindern, sind:


1. Deaktiviere die Bearbeitung von Dateien im WordPress-Admin-Bereich

Die Bearbeitung von Themes und Plugins direkt im WordPress-Dashboard ist ein hohes Sicherheitsrisiko. Wenn ein Angreifer Zugriff auf das Admin-Konto erhält, kann er schädlichen Code in jede Datei (einschließlich functions.php) einschleusen.

PHP

// Deaktiviert den Theme- und Plugin-Editor (empfohlen)
define( 'DISALLOW_FILE_EDIT', true );

Anmerkung: Diese Zeile wird oft direkt in der wp-config.php eingefügt, da sie eine globale Konfigurationsdirektive ist. Sie dient aber dem gleichen Sicherheitszweck.


2. Entferne die WordPress-Versionsnummer

Die Anzeige der genauen WordPress-Versionsnummer kann Angreifern nützliche Informationen liefern, wenn sie gezielt nach bekannten Schwachstellen in dieser Version suchen. Es ist besser, diese Informationen zu verbergen.

PHP

// Entfernt die WordPress-Versionsnummer aus Header, RSS und anderen Metadaten
function remove_wp_version_strings( $src ) {
    global $wp_version;
    parse_str( parse_url( $src, PHP_URL_QUERY ), $query );
    if ( !empty( $query['ver'] ) && $query['ver'] === $wp_version ) {
        $src = remove_query_arg( 'ver', $src );
    }
    return $src;
}
add_filter( 'script_loader_src', 'remove_wp_version_strings' );
add_filter( 'style_loader_src', 'remove_wp_version_strings' );

// Entfernt die Version aus dem <head>
remove_action( 'wp_head', 'wp_generator' );

3. Deaktiviere die XML-RPC-Schnittstelle (wenn nicht benötigt)

XML-RPC (xmlrpc.php) ist ein älteres Protokoll, das oft für Brute-Force-Angriffe und DDoS-Attacken missbraucht wird (insbesondere der pingback-Dienst). Wenn du keine mobilen Apps, Jetpack oder andere Dienste nutzt, die XML-RPC benötigen, solltest du es deaktivieren.

PHP

// Deaktiviert die XML-RPC-Schnittstelle
add_filter( 'xmlrpc_enabled', '__return_false' );

// Entfernt den RSD-Link (falls vorhanden)
remove_action( 'wp_head', 'rsd_link' );

4. Begrenze Login-Versuche

Um Brute-Force-Angriffe auf die Login-Seite (wp-login.php) zu verhindern, solltest du die Anzahl der möglichen Login-Versuche beschränken. Dies wird zwar oft über ein dediziertes Sicherheits-Plugin (z. B. Limit Login Attempts) gelöst, kann aber auch per PHP Code gesteuert werden.

PHP

// --- Konfiguration ---
define( 'MAX_LOGIN_ATTEMPTS', 5 );          // Max. Fehlversuche
define( 'LOCKOUT_DURATION', 3600 );        // Sperr-Dauer in Sekunden (1 Stunde)
define( 'TRANSIENT_PREFIX', 'limit_login_' );

/**
 * 1. Zählt fehlgeschlagene Versuche und setzt die Sperre.
 * Wird NACH dem Fehlschlag ausgeführt.
 */
function custom_increment_login_attempts( $username ) {
    $user_ip = $_SERVER['REMOTE_ADDR'];
    $transient_key = TRANSIENT_PREFIX . md5( $user_ip );

    // Zähler auslesen
    $attempts = (int) get_transient( $transient_key );
    $attempts++;

    if ( $attempts >= MAX_LOGIN_ATTEMPTS ) {
        // Sperren: Setze den Lockout-Transient
        set_transient( $transient_key . '_lockout', time() + LOCKOUT_DURATION, LOCKOUT_DURATION );
        // Zähler zurücksetzen/löschen
        delete_transient( $transient_key );
    } else {
        // Zähler erhöhen: Setze den Transient mit Ablaufzeit
        set_transient( $transient_key, $attempts, LOCKOUT_DURATION );
    }
}
// Hook zum Hochzählen des Fehlers
add_action( 'wp_login_failed', 'custom_increment_login_attempts' );


/**
 * 2. Prüft VOR der Anmeldung, ob die IP gesperrt ist.
 * Wird VOR der eigentlichen Authentifizierung ausgeführt.
 */
function custom_check_ip_lockout( $user ) {
    // Wenn die Authentifizierung bereits fehlgeschlagen ist oder erfolgreich war, nichts tun
    if ( is_wp_error( $user ) || ( $user instanceof WP_User ) ) {
        return $user;
    }

    $user_ip = $_SERVER['REMOTE_ADDR'];
    $lockout_key = TRANSIENT_PREFIX . md5( $user_ip ) . '_lockout';

    $lockout_time = get_transient( $lockout_key );

    if ( $lockout_time ) {
        $remaining_time = $lockout_time - time();

        if ( $remaining_time > 0 ) {
            // Die IP ist gesperrt
            $minutes = ceil( $remaining_time / 60 );
            return new WP_Error(
                'too_many_attempts_lockout',
                sprintf(
                    '<strong>FEHLER</strong>: Zu viele fehlgeschlagene Login-Versuche. Bitte versuche es in %s Minuten erneut.',
                    $minutes
                )
            );
        } else {
            // Sperre ist abgelaufen, den Lockout-Transient löschen
            delete_transient( $lockout_key );
        }
    }

    // Wenn nicht gesperrt, normal fortfahren
    return $user;
}
// Hook zum Blockieren der Anmeldung
add_filter( 'authenticate', 'custom_check_ip_lockout', 1 ); // Hohe Priorität, um sehr früh zu laufen

Zusammenfassung: Der Hook 'wp_login_failed' ist nützlich für das Zählen, und der Filter 'authenticate' ist unerlässlich für das Blockieren und die Ausgabe der Sperr-Meldung. Beide zusammen ergeben eine saubere, nicht-Plugin-basierte Lösung.


5. Deaktiviere die Enumeration von Benutzernamen

Standardmäßig ist es Angreifern leicht möglich, alle Benutzernamen deiner Seite zu ermitteln, indem sie spezielle URL-Parameter oder die REST API verwenden (z. B. /?author=1). Mit dem Wissen des Benutzernamens ist nur noch das Passwort für einen Login erforderlich. Das solltest du verhindern.

PHP

// Verhindert die Enumeration von Benutzernamen über die Author-URL
if ( !is_admin() && isset( $_SERVER['REQUEST_URI'] ) ) {
    if ( preg_match( '/author=([0-9]*)/i', $_SERVER['REQUEST_URI'] ) ) {
        wp_die( 'Zugriff verweigert.', 'Sicherheitshinweis', array( 'response' => 403 ) );
    }
}
// Blockiert die REST API Endpunkte für Benutzer (wenn nicht benötigt)
add_filter( 'rest_endpoints', function( $endpoints ) {
    if ( isset( $endpoints['/wp/v2/users'] ) ) {
        unset( $endpoints['/wp/v2/users'] );
    }
    if ( isset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ) ) {
        unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
    }
    return $endpoints;
} );

Wichtiger Hinweis:
Jede Änderung an der functions.php sollte in einem Child-Theme vorgenommen werden, damit die Änderungen bei einem Theme-Update nicht überschrieben werden! Fehler in dieser Datei können zum Absturz deiner gesamten Webseite führen.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert