Schwerwiegende Sicherheitslücken in Version 4.1.5.3 des All-in-One-SEO-Plug-ins behoben

Veröffentlicht: 2021-12-15

Während eines internen Audits des All-In-One-SEO-Plugins haben wir eine SQL-Injection-Schwachstelle und einen Privilege-Escalation-Bug aufgedeckt.

Wenn sie ausgenutzt wird, könnte die SQL-Injection-Schwachstelle Angreifern Zugriff auf privilegierte Informationen aus der Datenbank der betroffenen Site gewähren (z. B. Benutzernamen und gehashte Passwörter).

Der von uns entdeckte Privilege Escalation-Bug kann böswilligen Akteuren Zugriff auf geschützte REST-API-Endpunkte gewähren, auf die sie keinen Zugriff haben sollten. Dies könnte letztendlich Benutzern mit Konten mit geringen Berechtigungen, wie z. B. Abonnenten, ermöglichen, Remote-Codeausführung auf betroffenen Websites durchzuführen.

Wir haben die Schwachstellen dem Autor des Plugins per E-Mail gemeldet, und sie haben kürzlich Version 4.1.5.3 veröffentlicht, um sie zu beheben. Wir empfehlen dringend, dass Sie auf die neueste Plugin-Version aktualisieren und eine etablierte Sicherheitslösung auf Ihrer Website haben, wie z. B. Jetpack Security.

Einzelheiten

Plugin-Name: All-in-One-SEO
Plugin-URI: https://wordpress.org/plugins/all-in-one-seo-pack/
Autor: https://aioseo.com/

Die Schwachstellen

Authentifizierte Rechteausweitung

Betroffene Versionen: Alle Versionen zwischen 4.0.0 und 4.1.5.2 einschließlich.
CVE-ID: CVE-2021-25036
CVSSv3.1: 9.9
CWSS: 92.1

	/**
	 * Validates access from the routes array.
	 *
	 * @since 4.0.0
	 *
	 * @param  \WP_REST_Request $request The REST Request.
	 * @return bool                      True if validated, false if not.
	 */
	public function validateAccess( $request ) {
		$route     = str_replace( '/' . $this->namespace . '/', '', $request->get_route() );
		$routeData = isset( $this->getRoutes()[ $request->get_method() ][ $route ] ) ? $this->getRoutes()[ $request->get_method() ][ $route ] : [];

		// No direct route name, let's try the regexes.
		if ( empty( $routeData ) ) {
			foreach ( $this->getRoutes()[ $request->get_method() ] as $routeRegex => $routeInfo ) {
				$routeRegex = str_replace( '@', '\@', $routeRegex );
				if ( preg_match( "@{$routeRegex}@", $route ) ) {
					$routeData = $routeInfo;
					break;
				}
			}
		}

		if ( empty( $routeData['access'] ) ) {
			return true;
		}

		// We validate with any of the access options.
		if ( ! is_array( $routeData['access'] ) ) {
			$routeData['access'] = [ $routeData['access'] ];
		}
		foreach ( $routeData['access'] as $access ) {
			if ( current_user_can( $access ) ) {
				return true;
			}
		}

		if ( current_user_can( apply_filters( 'aioseo_manage_seo', 'aioseo_manage_seo' ) ) ) {
			return true;
		}

		return false;
	}

Die von All In One SEO angewendeten Berechtigungsprüfungen zum Sichern von REST-API-Endpunkten enthielten einen sehr subtilen Fehler, der Benutzern mit Konten mit geringen Berechtigungen (wie Abonnenten) Zugriff auf jeden einzelnen Endpunkt gewährt haben könnte, den das Plugin registriert.

Die Api::validateAccess()-Methode verlässt sich darauf, dass die angeforderte REST-API-Route weiß, welche Berechtigungsprüfungen für eine bestimmte Anforderung erzwungen werden sollen. Da die Tatsache nicht berücksichtigt wurde, dass WordPress REST-API-Routen als Zeichenfolgen behandelt, bei denen die Groß-/Kleinschreibung nicht beachtet wird, würde das Ändern eines einzelnen Zeichens in Großbuchstaben die Berechtigungsprüfungsroutine vollständig umgehen.

Dies ist besonders besorgniserregend, da einige der Endpunkte des Plugins ziemlich empfindlich sind. Beispielsweise kann der aioseo/v1/htaccess Endpunkt die .htaccess-Datei einer Website mit beliebigem Inhalt überschreiben. Ein Angreifer könnte diese Funktion missbrauchen, um .htaccess-Hintertüren zu verbergen und bösartigen Code auf dem Server auszuführen.

Authentifizierte SQL-Injection

Betroffene Versionen: Jede Version zwischen 4.1.3.1 und 4.1.5.2 einschließlich.
CVE-ID: CVE-2021-25037
CVSSv3.1: 7.7
CWSS: 80.4

/**
 * Searches for posts or terms by ID/name.
 *
 * @since 4.0.0
 *
 * @param  \WP_REST_Request  $request The REST Request
 * @return \WP_REST_Response          The response.
 */
public static function searchForObjects( $request ) {
    $body = $request->get_json_params();
 
    if ( empty( $body['query'] ) ) {
        return new \WP_REST_Response( [
            'success' => false,
            'message' => 'No search term was provided.'
        ], 400 );
    }
    if ( empty( $body['type'] ) ) {
        return new \WP_REST_Response( [
            'success' => false,
            'message' => 'No type was provided.'
        ], 400 );
    }
 
    $searchQuery = aioseo()->db->db->esc_like( $body['query'] );
 
    $objects        = [];
    $dynamicOptions = aioseo()->dynamicOptions->noConflict();
    if ( 'posts' === $body['type'] ) {
 
        $postTypes = aioseo()->helpers->getPublicPostTypes( true );
        foreach ( $postTypes as $postType ) {
            // Check if post type isn't noindexed.
            if ( $dynamicOptions->searchAppearance->postTypes->has( $postType ) && ! $dynamicOptions->searchAppearance->postTypes->$postType->show ) {
                $postTypes = aioseo()->helpers->unsetValue( $postTypes, $postType );
            }
        }
 
        $objects = aioseo()->db
            ->start( 'posts' )
            ->select( 'ID, post_type, post_title, post_name' )
            ->whereRaw( "( post_title LIKE '%{$searchQuery}%' OR post_name LIKE '%{$searchQuery}%' OR )" )
            ->whereIn( 'post_type', $postTypes )
            ->whereIn( 'post_status', [ 'publish', 'draft', 'future', 'pending' ] )
            ->orderBy( 'post_title' )
            ->limit( 10 )
            ->run()
            ->result();

Die Methode PostsTerms::searchForObjects(), auf die über die REST-API-Route /wp-json/aioseo/v1/objects zugegriffen werden kann, hat Benutzereingaben nur mit wpdb::esc_like() maskiert, bevor diese Eingabe an eine SQL-Abfrage angehängt wurde. Da diese Methode nicht darauf ausgelegt ist, Anführungszeichen zu maskieren, könnte ein Angreifer sie trotzdem einfügen und die Abfrage dazu zwingen, vertrauliche Informationen wie Benutzeranmeldeinformationen aus der Datenbank zu lecken.

Dieser Endpunkt sollte zwar nicht für Benutzer mit Konten mit geringen Berechtigungen zugänglich sein, aber der oben erwähnte Angriffsvektor zur Rechteausweitung ermöglichte es ihnen, diese Schwachstelle auszunutzen.

Zeitleiste

01.12.2021 – Erstkontakt mit All In One SEO
02.12.2021 – Wir senden ihnen Details zu diesen Schwachstellen
08.12.2021 – All In One SEO 4.1.5.3 wird veröffentlicht

Fazit

Wir empfehlen Ihnen, zu überprüfen, welche Version des All-In-One-SEO-Plug-Ins Ihre Website verwendet, und wenn es sich innerhalb des betroffenen Bereichs befindet, aktualisieren Sie es so schnell wie möglich!

Bei Jetpack arbeiten wir hart daran sicherzustellen, dass Ihre Websites vor dieser Art von Schwachstellen geschützt sind. Wir empfehlen, dass Sie einen Sicherheitsplan für Ihre Website haben, der das Scannen von bösartigen Dateien und Sicherungen umfasst. Jetpack Security ist eine großartige WordPress-Sicherheitsoption, um sicherzustellen, dass Ihre Website und Besucher sicher sind.

Kredite

Ursprünglicher Forscher: Marc Montpas

Danke an den Rest des Jetpack-Scan-Teams für Feedback, Hilfe und Korrekturen.