Kerentanan Parah Diperbaiki di All In One SEO Plugin Versi 4.1.5.3

Diterbitkan: 2021-12-15

Selama audit internal plugin All In One SEO, kami menemukan kerentanan SQL Injection dan bug Privilege Eskalasi.

Jika dieksploitasi, kerentanan SQL Injection dapat memberi penyerang akses ke informasi istimewa dari database situs yang terpengaruh (misalnya, nama pengguna dan kata sandi yang di-hash).

Bug Eskalasi Hak Istimewa yang kami temukan dapat memberikan akses kepada aktor jahat ke titik akhir REST API yang dilindungi yang seharusnya tidak mereka akses. Ini pada akhirnya dapat memungkinkan pengguna dengan akun dengan hak istimewa rendah, seperti pelanggan, untuk melakukan eksekusi kode jarak jauh di situs yang terpengaruh.

Kami melaporkan kerentanan kepada pembuat plugin melalui email, dan mereka baru-baru ini merilis versi 4.1.5.3 untuk mengatasinya. Kami sangat menyarankan Anda memperbarui ke versi plugin terbaru dan memiliki solusi keamanan yang mapan di situs Anda, seperti Jetpack Security.

rincian

Nama Plugin: Semua Dalam Satu SEO
URI Plugin: https://wordpress.org/plugins/all-in-one-seo-pack/
Pengarang: https://aioseo.com/

Kerentanan

Eskalasi Hak Istimewa yang Diautentikasi

Versi yang terpengaruh: Setiap versi antara 4.0.0 dan 4.1.5.2 secara inklusif.
ID-CVE: 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;
	}

Pemeriksaan hak istimewa yang diterapkan oleh All In One SEO untuk mengamankan titik akhir REST API berisi bug yang sangat halus yang dapat memberi pengguna dengan akun dengan hak istimewa rendah (seperti pelanggan) akses ke setiap titik akhir yang didaftarkan plugin.

Metode Api::validateAccess() bergantung pada rute REST API yang diminta untuk mengetahui pemeriksaan hak istimewa mana yang harus diterapkan pada permintaan yang diberikan. Karena tidak memperhitungkan fakta bahwa WordPress memperlakukan rute REST API sebagai string yang tidak peka huruf besar/kecil, mengubah satu karakter menjadi huruf besar akan sepenuhnya mengabaikan pemeriksaan rutin hak istimewa.

Ini sangat mengkhawatirkan karena beberapa titik akhir plugin cukup sensitif. Misalnya, titik akhir aioseo/v1/htaccess dapat menulis ulang .htaccess situs dengan konten arbitrer. Penyerang dapat menyalahgunakan fitur ini untuk menyembunyikan .htaccess backdoors dan mengeksekusi kode berbahaya di server.

Injeksi SQL Terautentikasi

Versi yang terpengaruh: Setiap versi antara 4.1.3.1 dan 4.1.5.2 secara inklusif.
ID-CVE: 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();

Metode PostsTerms::searchForObjects() , yang dapat diakses melalui rute /wp-json/aioseo/v1/objects REST API hanya lolos dari input pengguna menggunakan wpdb::esc_like() sebelum menambahkan input tersebut ke kueri SQL. Karena metode ini tidak dirancang untuk menghindari tanda kutip, penyerang masih dapat memasukkannya dan memaksa kueri untuk membocorkan informasi sensitif dari database, seperti kredensial pengguna.

Meskipun titik akhir ini tidak dimaksudkan untuk dapat diakses oleh pengguna dengan akun dengan hak istimewa rendah, vektor serangan eskalasi hak istimewa yang disebutkan di atas memungkinkan mereka untuk menyalahgunakan kerentanan ini.

Linimasa

2021-12-01 – Kontak awal dengan All In One SEO
2021-12-02 – Kami mengirimi mereka detail tentang kerentanan ini
2021-12-08 – All In One SEO 4.1.5.3 dirilis

Kesimpulan

Kami menyarankan Anda memeriksa versi plugin SEO All In One mana yang digunakan situs Anda, dan jika berada dalam kisaran yang terpengaruh, perbarui sesegera mungkin!

Di Jetpack, kami bekerja keras untuk memastikan situs web Anda terlindungi dari jenis kerentanan ini. Kami menyarankan Anda memiliki rencana keamanan untuk situs Anda yang mencakup pemindaian dan pencadangan file berbahaya. Jetpack Security adalah salah satu opsi keamanan WordPress yang bagus untuk memastikan situs dan pengunjung Anda aman.

kredit

Peneliti asli: Marc Montpas

Terima kasih kepada tim Jetpack Scan lainnya atas umpan balik, bantuan, dan koreksinya.