From 2acd3978eb86bd70c48291a7dfd0a04637e55b2b Mon Sep 17 00:00:00 2001 From: frantorres Date: Sun, 14 Jun 2026 21:32:13 +0200 Subject: [PATCH 1/2] Plugin directory: Prevent duplicated plugin submissions using guardrails both in the frontend and in the backend. --- .../plugin-directory/shortcodes/class-upload.php | 15 +++++++++++++-- .../themes/pub/wporg-plugins-2024/functions.php | 6 ++++++ .../themes/pub/wporg-plugins-2024/js/upload.js | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php b/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php index ea5d8acb0e..b32845c127 100644 --- a/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php +++ b/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php @@ -97,8 +97,19 @@ public static function display() { wp_verify_nonce( $_POST['_wpnonce'], 'wporg-plugins-upload-' . $_POST['plugin_id'] ) ) ) { - $for_plugin = absint( $_POST['plugin_id'] ?? 0 ); - $upload_result = $uploader->process_upload( $for_plugin ); + $for_plugin = absint( $_POST['plugin_id'] ?? 0 ); + + // Lock to prevent duplicate submissions from double-clicks or page reloads + $lock_key = 'plugin_upload_lock_' . get_current_user_id() . '_' . $for_plugin; + if ( false === wp_cache_add( $lock_key, time(), 'wporg-plugins', 5 * MINUTE_IN_SECONDS ) ) { + $upload_result = new \WP_Error( + 'upload_in_progress', + __( 'Your previous upload is still being processed. Please wait a moment before trying again.', 'wporg-plugins' ) + ); + } else { + $upload_result = $uploader->process_upload( $for_plugin ); + wp_cache_delete( $lock_key, 'wporg-plugins' ); + } if ( is_wp_error( $upload_result ) ) { $type = 'error'; diff --git a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php index e798728a31..6662070d15 100644 --- a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php +++ b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php @@ -137,6 +137,12 @@ function scripts() { // The plugin submission page: /developers/add/ if ( is_page( 'add' ) ) { wp_enqueue_script( 'wporg-plugins-upload', get_stylesheet_directory_uri() . '/js/upload.js', array( 'wp-api', 'jquery' ), filemtime( __DIR__ . '/js/upload.js' ), true ); + + wp_localize_script( 'wporg-plugins-upload', 'pluginUpload', array( + 'l10n' => array( + 'uploading' => __( 'Uploading…', 'wporg-plugins' ), + ), + ) ); } // No Jetpack scripts needed. diff --git a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js index 3212ec6a3f..cbd3028c3c 100644 --- a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js +++ b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/upload.js @@ -49,4 +49,19 @@ $(this).hide().parents('ul').find('.plugin-upload-form.hidden').removeClass( 'hidden' ); } ); + // Prevent duplicate submissions by disabling the submit button + $( 'form.plugin-upload-form' ).on( 'submit', function() { + var $button = $(this).find( 'input[type="submit"]' ); + + $button.prop( 'disabled', true ); + + if ( ! $button.data( 'defaultValue' ) ) { + $button.data( 'defaultValue', $button.val() ); + } + + if ( 'undefined' !== typeof pluginUpload && pluginUpload.l10n && pluginUpload.l10n.uploading ) { + $button.val( pluginUpload.l10n.uploading ); + } + } ); + })( jQuery ); From d96440b7f3ce8f8aa8ecb05a82c14a46bcf21f73 Mon Sep 17 00:00:00 2001 From: frantorres Date: Sun, 14 Jun 2026 21:45:16 +0200 Subject: [PATCH 2/2] Linting --- .../themes/pub/wporg-plugins-2024/functions.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php index 6662070d15..b988f44eef 100644 --- a/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php +++ b/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php @@ -138,11 +138,15 @@ function scripts() { if ( is_page( 'add' ) ) { wp_enqueue_script( 'wporg-plugins-upload', get_stylesheet_directory_uri() . '/js/upload.js', array( 'wp-api', 'jquery' ), filemtime( __DIR__ . '/js/upload.js' ), true ); - wp_localize_script( 'wporg-plugins-upload', 'pluginUpload', array( - 'l10n' => array( - 'uploading' => __( 'Uploading…', 'wporg-plugins' ), - ), - ) ); + wp_localize_script( + 'wporg-plugins-upload', + 'pluginUpload', + array( + 'l10n' => array( + 'uploading' => __( 'Uploading…', 'wporg-plugins' ), + ), + ) + ); } // No Jetpack scripts needed.