Μετάβαση στο περιεχόμενο
Κρίσιμη ευπάθεια ανεβάσματος αρχείων στο Elementor Pro: ενημερώστε στην έκδοση 4.2.2
Ελένη Γεωργίου
Ελένη Γεωργίου 20 August 2026 · 6 λεπτά ανάγνωσης

Κρίσιμη ευπάθεια ανεβάσματος αρχείων στο Elementor Pro: ενημερώστε στην έκδοση 4.2.2

Το Elementor Pro διόρθωσε μια κρίσιμη ευπάθεια αυθαίρετου ανεβάσματος αρχείων, με βαθμολογία CVSS 9.8/10. Η ευπάθεια επηρεάζει όλες τις εκδόσεις έως και την 4.2.1 και επιτρέπει σε επισκέπτη χωρίς λογαριασμό να ανεβάσει εκτελέσιμο αρχείο PHP, με πιθανό αποτέλεσμα την απομακρυσμένη εκτέλεση κώδικα και την πλήρη κατάληψη του site.

Η ευπάθεια καταγράφηκε ως CVE-2026-32475 και διορθώνεται στην Elementor Pro 4.2.2. Για να είναι εκμεταλλεύσιμος ένας ιστότοπος, πρέπει να έχει δημοσιευμένη σελίδα με Form widget του Elementor Pro και τουλάχιστον ένα πεδίο File Upload που δεν έχει οριστεί ως υποχρεωτικό.

Ποιοι ιστότοποι επηρεάζονται

Η ευπάθεια αφορά το Elementor Website Builder Pro, δηλαδή το elementor-pro, στις εκδόσεις ≤ 4.2.1. Το Elementor Pro επεκτείνει τον Elementor page builder με πρόσθετα widgets, μεταξύ τους το Form widget που υποστηρίζει πεδία για ανέβασμα αρχείων.

  • Ελέγξτε αν το site χρησιμοποιεί Elementor Pro 4.2.1 ή παλαιότερη έκδοση.
  • Ελέγξτε τις δημοσιευμένες σελίδες που περιέχουν Form widget.
  • Δώστε ιδιαίτερη προσοχή σε πεδία File Upload που δεν είναι υποχρεωτικά.
  • Μην θεωρήσετε ότι το πρόβλημα περιορίζεται σε συνδεδεμένους χρήστες: ο επιτιθέμενος δεν χρειάζεται αυθεντικοποίηση.

Πώς παρακάμπτεται η επικύρωση αρχείων

Το Form widget δέχεται υποβολές μέσω της ajax_send_form() στην κλάση Ajax_Handler, την οποία μπορούν να καλέσουν και επισκέπτες χωρίς σύνδεση. Το plugin τυλίγει τα δεδομένα της φόρμας, μαζί με τα ανεβασμένα αρχεία, σε αντικείμενο Form_Record και τα περνά από τις ρουτίνες επικύρωσης και επεξεργασίας του ElementorProModulesFormsFieldsUpload.

Για τα πεδία File Upload, η ροή καταλήγει στις validation() και process_field(). Το σφάλμα βρίσκεται στη validation(): όταν το πεδίο δεν είναι υποχρεωτικό και το πρώτο στοιχείο του πίνακα αρχείων έχει σφάλμα UPLOAD_ERR_NO_FILE, η συνάρτηση χρησιμοποιεί return. Έτσι τερματίζει ολόκληρη την επικύρωση αντί να παραλείψει μόνο το κενό στοιχείο.

public function validation( $field, ClassesForm_Record $record, ClassesAjax_Handler $ajax_handler ) {
    static $upload_errors = false;

    if ( ! $upload_errors ) {
        $upload_errors = [
            UPLOAD_ERR_OK => esc_html__( 'There is no error, the file uploaded with success.', 'elementor-pro' ),
            UPLOAD_ERR_INI_SIZE => sprintf( esc_html__( 'The uploaded file exceeds the %1$s directive in %2$s.', 'elementor-pro' ), 'upload_max_filesize', 'php.ini' ),
            UPLOAD_ERR_FORM_SIZE => sprintf( esc_html__( 'The uploaded file exceeds the %s directive that was specified in the HTML form.', 'elementor-pro' ), 'MAX_FILE_SIZE' ),
            UPLOAD_ERR_PARTIAL => esc_html__( 'The uploaded file was only partially uploaded.', 'elementor-pro' ),
            UPLOAD_ERR_NO_FILE => esc_html__( 'No file was uploaded.', 'elementor-pro' ),
            UPLOAD_ERR_NO_TMP_DIR => esc_html__( 'Missing a temporary folder.', 'elementor-pro' ),
            UPLOAD_ERR_CANT_WRITE => esc_html__( 'Failed to write file to disk.', 'elementor-pro' ),
            UPLOAD_ERR_EXTENSION => sprintf( esc_html__( 'A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with %s may help.', 'elementor-pro' ), 'phpinfo()' ),
        ];
    }

    $this->fix_file_indices();
    $id = $field['id'];
    $files = Utils::_unstable_get_super_global_value( $_FILES, 'form_fields' );

    if ( ! empty( $field['max_files'] ) ) {
        if ( count( $files[$id] ) > $field['max_files'] ) {
            $error_message = sprintf(
                _n( 'You can upload only %d file.', 'You can upload up to %d files.', intval( $field['max_files'] ), 'elementor-pro' ),
                intval( $field['max_files'] )
            );
            $ajax_handler->add_error( $id, $error_message );
            return;
        }
    }

    foreach ( $files[$id] as $index => $file ) {
        // Το return διακόπτει τον έλεγχο όλων των επόμενων αρχείων.
        if ( ! $field['required'] && UPLOAD_ERR_NO_FILE === $file['error'] ) {
            return;
        }

        if ( $field['required'] && UPLOAD_ERR_NO_FILE === $file['error'] ) {
            $ajax_handler->add_error( $id, $upload_errors[$file['error']] );
            return;
        }

        if ( $file['error'] > UPLOAD_ERR_OK ) {
            $ajax_handler->add_error( $id, $upload_errors[$file['error']] );
            return;
        }

        if ( ! $this->is_file_type_valid( $field, $file ) ) {
            $ajax_handler->add_error( $id, esc_html__( 'This file type is not allowed.', 'elementor-pro' ) );
        }

        if ( ! $this->is_file_size_valid( $field, $file ) ) {
            $ajax_handler->add_error( $id, esc_html__( 'This file exceeds the maximum allowed size.', 'elementor-pro' ) );
        }
    }
}

Η αναμενόμενη συμπεριφορά ήταν continue, ώστε ο βρόχος να αγνοεί την κενή θέση και να συνεχίζει με το επόμενο αρχείο. Με το return, όμως, δεν εκτελούνται οι έλεγχοι επέκτασης μέσω της is_file_type_valid() ούτε οι έλεγχοι μεγέθους για τα υπόλοιπα στοιχεία του ίδιου πεδίου.

Η αλυσίδα εκμετάλλευσης

Ο επιτιθέμενος υποβάλλει το πεδίο ανεβάσματος ως πίνακα με δύο μέρη. Το πρώτο είναι κενό και προκαλεί UPLOAD_ERR_NO_FILE, άρα ενεργοποιεί τον πρόωρο τερματισμό της validation(). Στο δεύτερο μέρος τοποθετεί PHP payload με επέκταση αρχείου που επιλέγει ο ίδιος, χωρίς ο κώδικας να ελέγξει τον τύπο ή το μέγεθός του.

Η process_field() χειρίζεται διαφορετικά την κενή πρώτη θέση: χρησιμοποιεί σωστά continue, συνεχίζει στο δεύτερο στοιχείο και το επεξεργάζεται παρότι δεν επικυρώθηκε. Επιπλέον, παίρνει την επέκταση απευθείας από το όνομα αρχείου που έστειλε ο client.

public function process_field( $field, ClassesForm_Record $record, ClassesAjax_Handler $ajax_handler ) {
    $id = $field['id'];
    $files = Utils::_unstable_get_super_global_value( $_FILES, 'form_fields' );

    foreach ( $files[$id] as $index => $file ) {
        if ( UPLOAD_ERR_NO_FILE === $file['error'] ) {
            continue;
        }

        $uploads_dir = $this->get_ensure_upload_dir();
        $file_extension = pathinfo( $file['name'], PATHINFO_EXTENSION );
        $filename = uniqid() . '.' . $file_extension;
        $filename = wp_unique_filename( $uploads_dir, $filename );
        $new_file = trailingslashit( $uploads_dir ) . $filename;

        if ( is_dir( $uploads_dir ) && is_writable( $uploads_dir ) ) {
            $move_new_file = Plugin::instance()->php_api->move_uploaded_file( $file['tmp_name'], $new_file );

            if ( false !== $move_new_file ) {
                // Ορίζει δικαιώματα αρχείου 0644.
                $perms = 0644;
                @chmod( $new_file, $perms );

                $record->add_file( $id, $index, [
                    'path' => $new_file,
                    'url' => $this->get_file_url( $filename ),
                ] );
            } else {
                $ajax_handler->add_error( $id, esc_html__( 'There was an error while trying to upload your file.', 'elementor-pro' ) );
            }
        } else {
            $ajax_handler->add_admin_error_message( esc_html__( 'Upload directory is not writable or does not exist.', 'elementor-pro' ) );
        }
    }
}

Το plugin διατηρεί την επέκταση από το όνομα που έστειλε ο επιτιθέμενος και γράφει, για παράδειγμα, ένα αρχείο με επέκταση .php στον κατάλογο /wp-content/uploads/elementor/forms/. Ο επιτιθέμενος μπορεί στη συνέχεια να ζητήσει το URL του αρχείου, να εκτελέσει το PHP payload στον server και να χρησιμοποιήσει webshell ή άλλες τεχνικές για να θέσει τον ιστότοπο υπό τον έλεγχό του.

Χρονολόγιο της διόρθωσης

  1. 24 Ιουλίου 2026: Η Wordfence έλαβε αναφορά για τη μη αυθεντικοποιημένη ευπάθεια αυθαίρετου ανεβάσματος αρχείων στο Elementor Pro.
  2. 27 Ιουλίου 2026: Επιβεβαιώθηκε η αναφορά και το proof of concept, και γνωστοποιήθηκε η ευπάθεια στην ομάδα του Elementor.
  3. 2 Αυγούστου 2026: Ο προμηθευτής ανέφερε ότι είχε λάβει και ανεξάρτητη αναφορά για το ίδιο ζήτημα και ότι εργαζόταν σε διόρθωση.
  4. 19 Αυγούστου 2026: Κυκλοφόρησε η Elementor Pro 4.2.2 με πλήρη διόρθωση.

Τι να κάνετε τώρα

Ενημερώστε άμεσα το Elementor Pro στην έκδοση 4.2.2 ή σε νεότερη διαθέσιμη έκδοση. Μην περιοριστείτε στον έλεγχο του core του WordPress: η διόρθωση βρίσκεται στο plugin και οι εκδόσεις έως την 4.2.1 παραμένουν ευάλωτες.

  1. Ανοίξτε τη διαχείριση του WordPress και επιβεβαιώστε την εγκατεστημένη έκδοση του Elementor Pro.
  2. Αναβαθμίστε στην 4.2.2 ή σε μεταγενέστερη έκδοση.
  3. Ελέγξτε αν υπάρχουν δημοσιευμένες φόρμες με προαιρετικά πεδία File Upload.
  4. Εξετάστε τον κατάλογο /wp-content/uploads/elementor/forms/ για άγνωστα αρχεία, ιδιαίτερα αρχεία με επέκταση .php, και ακολουθήστε τη διαδικασία αντιμετώπισης περιστατικού αν εντοπίσετε ύποπτο περιεχόμενο.
Ελένη Γεωργίου

Ελένη Γεωργίου

Προγραμματίστρια τουριστικής τεχνολογίας και πλατφορμών φιλοξενίας. Συστήματα online κρατήσεων και λογισμικό φιλοξενίας είναι ο τομέας μου. Η μεσογειακή φιλοξενία λειτουργεί και ψηφιακά.

Όλες οι αναρτήσεις

Γίνετε μέλος της κοινότητας HelloWP!

Συζητήστε μαζί μας για WordPress, web development και μοιραστείτε εμπειρίες με άλλους προγραμματιστές.

- μέλη
- σε σύνδεση
Συμμετοχή

Χρησιμοποιούμε cookies για να βελτιώσουμε την εμπειρία σας. Συνεχίζοντας, συμφωνείτε με την Πολιτική Cookies μας.