WordPress Rest API Schnittstelle mit Firewall
Veröffentlicht am: 22.05.2024 | Letztes Update am: 22.05.24 | Lesezeit: 6 Minute/n


Registrierung der benutzerdefinierten REST-Route

Die Funktion zur Registrierung der REST-API-Route wird verwendet, um einen neuen Endpunkt in WordPress hinzuzufügen. Dieser Endpunkt ermöglicht es, externe Anfragen an WordPress zu senden und eine Antwort zu erhalten.

Schritte der Registrierung:

Hook zur Initialisierung der REST-API: Mit add_action('rest_api_init', function () { … }); wird eine anonyme Funktion registriert, die während der Initialisierung der REST-API aufgerufen wird.
Definition der Route: Innerhalb dieser anonymen Funktion wird register_rest_route aufgerufen, um die Route zu definieren.
Namespace: 'hnp_api_firewall/v1' legt den Namespace fest, der als Versionierung der API dient.
Route: '/api' ist der spezifische Endpunkt innerhalb des Namespace.
Optionen: Ein Array von Optionen, darunter:
Methode: 'methods' => 'POST' spezifiziert, dass die Route nur POST-Anfragen akzeptiert.
Callback: 'callback' => 'hnp_api_firewall_callback' gibt die Funktion an, die aufgerufen wird, wenn die Route erreicht wird.
Berechtigung: 'permission_callback' => 'hnp_api_firewall_combined_permissions' bestimmt die Funktion, die die Berechtigungen für den Zugriff auf die Route überprüft.

Kombinierte Berechtigungs- und Blockierungslogik

Die Funktion hnp_api_firewall_combined_permissions dient dazu, die Berechtigungen und Blockierungslogik zu kombinieren. Sie wird aufgerufen, bevor die Haupt-Callback-Funktion ausgeführt wird, um sicherzustellen, dass nur berechtigte Anfragen zugelassen werden.

Schritte der Berechtigungsprüfung:

IP-Überprüfung: Die IP-Adresse des Anfragenden wird überprüft, um festzustellen, ob sie blockiert ist.
Wenn die IP-Adresse blockiert ist und die Blockierungsdauer noch nicht abgelaufen ist, wird der Zugriff verweigert.
Wenn die Blockierungsdauer abgelaufen ist, wird die IP-Adresse entsperrt und die Blockierungsinformationen werden zurückgesetzt.

Überprüfung der API-Benutzer und -Geheimnisse: Die Kopfzeilen der Anfrage werden auf gültige API-Benutzer und -Geheimnisse überprüft.
Wenn die Anmeldedaten korrekt sind, wird der Zähler für gültige Versuche erhöht.
Wenn die Anmeldedaten falsch sind, wird der Zähler für ungültige Versuche erhöht.
Wenn die Anzahl ungültiger Versuche einen bestimmten Schwellenwert überschreitet (z.B. 50), wird die IP-Adresse blockiert.

Versuchsverfolgung: Die Anzahl der erfolgreichen und fehlgeschlagenen Anmeldeversuche wird verfolgt, um die Blockierungslogik zu unterstützen.

Rückgabewert

Erfolgreiche Berechtigung: Wenn die Berechtigung erfolgreich ist, gibt die Funktion true zurück, wodurch die Haupt-Callback-Funktion hnp_api_firewall_callback aufgerufen wird.
Fehlgeschlagene Berechtigung: Wenn die Berechtigung fehlschlägt, wird ein Fehler zurückgegeben und die Haupt-Callback-Funktion wird nicht ausgeführt.

Haupt-Callback-Funktion

Die Haupt-Callback-Funktion hnp_api_firewall_callback wird aufgerufen, wenn die Berechtigung erfolgreich ist und die Route erreicht wird. Sie gibt eine JSON-Antwort mit dem Dateninhalt zurück, der in diesem Fall ein einfaches Beispiel mit {"testdata": "test"} ist.


// Register the custom REST route
add_action('rest_api_init', function () {
    register_rest_route('hnp_api_firewall/v1', '/api', array(
        'methods' => 'POST',
        'callback' => 'hnp_api_firewall_callback',
        'permission_callback' => 'hnp_api_firewall_combined_permissions',
    ));
});

// Combined function to handle permissions and blocking logic
function hnp_api_firewall_combined_permissions(WP_REST_Request $request) {
    $ip_address = sanitize_text_field($_SERVER['REMOTE_ADDR']);
    $blocked_ips = get_option('hnp_blocked_ips', array());

    // Check if IP is blocked
    if (isset($blocked_ips[$ip_address])) {
        $block_info = $blocked_ips[$ip_address];
        $block_time = $block_info['block_time'];
        $block_duration = $block_info['block_duration'];
        $current_time = current_time('timestamp');

        // If current time is less than block time + block duration, deny access
        if ($current_time < ($block_time + $block_duration)) {
            return new WP_Error('blocked_ip', 'Your IP is temporarily blocked due to too many attempts.', array('status' => 403));
        } else {
            // Unblock IP and reset attempts after block duration
            unset($blocked_ips[$ip_address]);
            update_option('hnp_blocked_ips', $blocked_ips);
        }
    }

    // Check API user and secret
    $api_user = $request->get_header('APIUser');
    $api_secret = $request->get_header('APISecret');
    $valid_api_user = '4GI53seaRLu!FK9XEiAk323U6M!f2bT7Sda28ZqsaegQCn0!Y121Y1L';
    $valid_api_secret = '091572EddV!YcTKGR3Q13a!CM6TN!UWbPqFRdwa1XpP!1g8o32aaJD4';

    // Tracking attempts
    $attempts = get_option('hnp_attempts', array());

    if (!isset($attempts[$ip_address])) {
        $attempts[$ip_address] = array(
            'valid_count' => 0,
            'invalid_count' => 0,
            'invalid_license_count' => 0,
            'first_attempt_time' => current_time('timestamp')
        );
    }

    $permission_granted = null !== $api_user && $api_user === $valid_api_user && null !== $api_secret && $api_secret === $valid_api_secret;

    if ($permission_granted) {
        $attempts[$ip_address]['valid_count']++;
    } else {
        $attempts[$ip_address]['invalid_count']++;

        // Block IP if invalid attempts exceed threshold (e.g., 50)
        if ($attempts[$ip_address]['invalid_count'] >= 50) {
            $blocked_ips[$ip_address] = array('block_time' => current_time('timestamp'), 'block_duration' => 12 * HOUR_IN_SECONDS);
            update_option('hnp_blocked_ips', $blocked_ips);
            return new WP_Error('blocked_ip', 'Your IP is temporarily blocked due to too many invalid attempts for API Secret/Username.', array('status' => 403));
        }

        update_option('hnp_attempts', $attempts);
        return new WP_Error('invalid_credentials', 'Invalid API Secret key or password.', array('status' => 403));
    }

    // Reset invalid attempts on successful authentication
    if (isset($attempts[$ip_address])) {
        unset($attempts[$ip_address]['invalid_count']);
        update_option('hnp_attempts', $attempts);
    }

    return true;
}

function hnp_api_firewall_callback() {
    return new WP_REST_Response(array(
        'testdata' => 'test'
    ), 200);
}

cUrl Anfrage zum Testen:

curl -X POST https://yourdomain.com/wp-json/hnp_api_firewall/v1/api \
     -H "APIUser: 4GI53seaRLu!FK9XEiAk323U6M!f2bT7Sda28ZqsaegQCn0!Y121Y1L" \
     -H "APISecret: 091572EddV!YcTKGR3Q13a!CM6TN!UWbPqFRdwa1XpP!1g8o32aaJD4"

PHP Anfrage zum Testen:

<?php

function call_hnp_api_firewall() {
    $url = 'https://yourdomain.com/wp-json/hnp_api_firewall/v1/api';
    
    $args = array(
        'headers' => array(
            'APIUser' => '4GI53seaRLu!FK9XEiAk323U6M!f2bT7Sda28ZqsaegQCn0!Y121Y1L',
            'APISecret' => '091572EddV!YcTKGR3Q13a!CM6TN!UWbPqFRdwa1XpP!1g8o32aaJD4'
        ),
        'body' => array(
            // Any additional data you want to send in the body
        )
    );

    $response = wp_remote_post($url, $args);

    if (is_wp_error($response)) {
        $error_message = $response->get_error_message();
        echo "Something went wrong: $error_message";
    } else {
        $response_body = wp_remote_retrieve_body($response);
        echo 'Response:<br>';
        echo '<pre>';
        print_r(json_decode($response_body, true));
        echo '</pre>';
    }
}

// Call the function
call_hnp_api_firewall();

?>

C# Anfrage zum Testen:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

class Program
{
    private static async Task CallHnpApiFirewallAsync()
    {
        var url = "https://yourdomain.com/wp-json/hnp_api_firewall/v1/api";
        
        using (var client = new HttpClient())
        {
            // Set the APIUser and APISecret headers
            client.DefaultRequestHeaders.Add("APIUser", "4GI53seaRLu!FK9XEiAk323U6M!f2bT7Sda28ZqsaegQCn0!Y121Y1L");
            client.DefaultRequestHeaders.Add("APISecret", "091572EddV!YcTKGR3Q13a!CM6TN!UWbPqFRdwa1XpP!1g8o32aaJD4");

            // Optionally set the content of the request (if needed)
            var content = new StringContent("", System.Text.Encoding.UTF8, "application/json");

            try
            {
                var response = await client.PostAsync(url, content);

                if (response.IsSuccessStatusCode)
                {
                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine("Response:");
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine($"Error: {response.StatusCode}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception: {ex.Message}");
            }
        }
    }

    static void Main(string[] args)
    {
        Task.Run(() => CallHnpApiFirewallAsync()).GetAwaiter().GetResult();
    }
}

Sicherheit:

Anzahl der möglichen Kombinationen bei BrutForceAttacken

Einzelne Schlüssel:

Für einen einzelnen Schlüssel mit 50 Zeichen und 94 möglichen Zeichen pro Position ergibt sich:
945094 hoch50
Zwei Schlüssel kombiniert

Da beide Schlüssel unabhängig voneinander betrachtet werden, multiplizieren wir die Anzahl der möglichen Kombinationen beider Schlüssel:

(94 hoch50)×(94 hoch50)(94 hoch50)×(94 hoch50)

Dies entspricht:
9410094 hoch100

Zeit für einen Brute-Force-Angriff

Angenommen, ein Computer kann 1 Milliarde (1.000.000.000) Kombinationen pro Sekunde testen:

Anzahl der Kombinationen:
Die Anzahl der Kombinationen für einen Schlüssel: 945094 hoch50 (eine extrem große Zahl)
Die Anzahl der Kombinationen für beide Schlüssel: 9410094 hoch100 (noch viel größer)

Zeit für Brute-Force:
Selbst wenn ein Computer 1 Milliarde Kombinationen pro Sekunde testen könnte, würde das Testen aller Kombinationen von zwei Schlüsseln extrem lange dauern.
Zum Vergleich:
Eine Milliarde Sekunden sind etwa 31,7 Jahre.

Die Anzahl der Kombinationen für 9410094 hoch100 ist so groß, dass selbst mit extrem schneller Hardware Billionen von Jahren benötigt würden, um alle Kombinationen zu testen.

Durch die Rate Limitierung der Firewall wird die Zeit auf Milliarden von Jahren erhöht, zudem sind DDOS oder ähnliche Hacking-Angriffe nicht möglich. Die Schnittstelle wird somit zusätzlich geschützt.

Avatar
Homepage-nach-Preis

Homepage-nach-Preis DE ist eine Werbeagentur für Onlinemarketing und aktiv in der Webentwicklung tätig. Spezialisierungen wie Suchmaschinenoptimierung (SEO), Webdesign und Conversion sind feste Bestandteile des Unternehmens..

View admin Posts


↩ Zurück zur Blogübersicht

Die Webseite ist gerade offline.

>