Index: src/wp-admin/admin-post.php
===================================================================
--- src/wp-admin/admin-post.php	(revision 34051)
+++ src/wp-admin/admin-post.php	(working copy)
@@ -28,7 +28,7 @@
 /** This action is documented in wp-admin/admin.php */
 do_action( 'admin_init' );
 
-$action = empty( $_REQUEST['action'] ) ? '' : $_REQUEST['action'];
+$action = wp_validate_action();
 
 if ( ! wp_validate_auth_cookie() ) {
 	if ( empty( $action ) ) {
Index: src/wp-admin/admin.php
===================================================================
--- src/wp-admin/admin.php	(revision 34051)
+++ src/wp-admin/admin.php	(working copy)
@@ -358,14 +358,16 @@
 	}
 }
 
-if ( ! empty( $_REQUEST['action'] ) ) {
+$_action = wp_validate_action();
+if ( ! empty( $_action ) ) {
 	/**
 	 * Fires when an 'action' request variable is sent.
 	 *
-	 * The dynamic portion of the hook name, `$_REQUEST['action']`,
+	 * The dynamic portion of the hook name, `$_action`,
 	 * refers to the action derived from the `GET` or `POST` request.
 	 *
 	 * @since 2.6.0
 	 */
-	do_action( 'admin_action_' . $_REQUEST['action'] );
+	do_action( 'admin_action_' . $_action );
 }
+unset( $_action );
Index: src/wp-admin/async-upload.php
===================================================================
--- src/wp-admin/async-upload.php	(revision 34051)
+++ src/wp-admin/async-upload.php	(working copy)
@@ -6,6 +6,7 @@
  * @subpackage Administration
  */
 
+// `wp_validate_action()` isn't loaded yet
 if ( isset( $_REQUEST['action'] ) && 'upload-attachment' === $_REQUEST['action'] ) {
 	define( 'DOING_AJAX', true );
 }
@@ -19,7 +20,7 @@
 else
 	require_once( dirname( dirname( __FILE__ ) ) . '/wp-load.php' );
 
-if ( ! ( isset( $_REQUEST['action'] ) && 'upload-attachment' == $_REQUEST['action'] ) ) {
+if ( ! wp_validate_action( 'upload-attachment' ) ) {
 	// Flash often fails to send cookies with the POST or upload, so we need to pass it in GET or POST instead
 	if ( is_ssl() && empty($_COOKIE[SECURE_AUTH_COOKIE]) && !empty($_REQUEST['auth_cookie']) )
 		$_COOKIE[SECURE_AUTH_COOKIE] = $_REQUEST['auth_cookie'];
@@ -34,7 +35,7 @@
 
 header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
 
-if ( isset( $_REQUEST['action'] ) && 'upload-attachment' === $_REQUEST['action'] ) {
+if ( wp_validate_action( 'upload-attachment' ) ) {
 	include( ABSPATH . 'wp-admin/includes/ajax-actions.php' );
 
 	send_nosniff_header();
Index: src/wp-admin/includes/class-wp-terms-list-table.php
===================================================================
--- src/wp-admin/includes/class-wp-terms-list-table.php	(revision 34051)
+++ src/wp-admin/includes/class-wp-terms-list-table.php	(working copy)
@@ -153,7 +153,8 @@
 	 * @return string
 	 */
 	public function current_action() {
-		if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['delete_tags'] ) && ( 'delete' == $_REQUEST['action'] || 'delete' == $_REQUEST['action2'] ) )
+		$action = wp_validate_action();
+		if ( $action && isset( $_REQUEST['delete_tags'] ) && ( 'delete' == $action || 'delete' == $_REQUEST['action2'] ) )
 			return 'bulk-delete';
 
 		return parent::current_action();
Index: src/wp-admin/network/site-info.php
===================================================================
--- src/wp-admin/network/site-info.php	(revision 34051)
+++ src/wp-admin/network/site-info.php	(working copy)
@@ -53,7 +53,7 @@
 $parsed_scheme = parse_url( $details->siteurl, PHP_URL_SCHEME );
 $is_main_site = is_main_site( $id );
 
-if ( isset( $_REQUEST['action'] ) && 'update-site' == $_REQUEST['action'] ) {
+if ( wp_validate_action( 'update-site' ) ) {
 	check_admin_referer( 'edit-site' );
 
 	switch_to_blog( $id );
Index: src/wp-admin/network/site-new.php
===================================================================
--- src/wp-admin/network/site-new.php	(revision 34051)
+++ src/wp-admin/network/site-new.php	(working copy)
@@ -33,7 +33,7 @@
 	'<p>' . __('<a href="https://wordpress.org/support/forum/multisite/" target="_blank">Support Forums</a>') . '</p>'
 );
 
-if ( isset($_REQUEST['action']) && 'add-site' == $_REQUEST['action'] ) {
+if ( wp_validate_action( 'add-site' ) ) {
 	check_admin_referer( 'add-blog', '_wpnonce_add-blog' );
 
 	if ( ! is_array( $_POST['blog'] ) )
Index: src/wp-admin/network/site-settings.php
===================================================================
--- src/wp-admin/network/site-settings.php	(revision 34051)
+++ src/wp-admin/network/site-settings.php	(working copy)
@@ -48,7 +48,7 @@
 
 $is_main_site = is_main_site( $id );
 
-if ( isset($_REQUEST['action']) && 'update-site' == $_REQUEST['action'] && is_array( $_POST['option'] ) ) {
+if ( wp_validate_action( 'update-site' ) && is_array( $_POST['option'] ) ) {
 	check_admin_referer( 'edit-site' );
 
 	switch_to_blog( $id );
Index: src/wp-admin/network/user-new.php
===================================================================
--- src/wp-admin/network/user-new.php	(revision 34051)
+++ src/wp-admin/network/user-new.php	(working copy)
@@ -30,7 +30,7 @@
 	'<p>' . __('<a href="https://wordpress.org/support/forum/multisite/" target="_blank">Support Forums</a>') . '</p>'
 );
 
-if ( isset($_REQUEST['action']) && 'add-user' == $_REQUEST['action'] ) {
+if ( wp_validate_action( 'add-user' ) ) {
 	check_admin_referer( 'add-user', '_wpnonce_add-user' );
 
 	if ( ! current_user_can( 'manage_network_users' ) )
Index: src/wp-admin/network/users.php
===================================================================
--- src/wp-admin/network/users.php	(revision 34051)
+++ src/wp-admin/network/users.php	(working copy)
@@ -174,11 +174,12 @@
 
 require_once( ABSPATH . 'wp-admin/admin-header.php' );
 
-if ( isset( $_REQUEST['updated'] ) && $_REQUEST['updated'] == 'true' && ! empty( $_REQUEST['action'] ) ) {
+$action = wp_validate_action();
+if ( isset( $_REQUEST['updated'] ) && $_REQUEST['updated'] == 'true' && ! empty( $action ) ) {
 	?>
 	<div id="message" class="updated notice is-dismissible"><p>
 		<?php
-		switch ( $_REQUEST['action'] ) {
+		switch ( $action ) {
 			case 'delete':
 				_e( 'User deleted.' );
 			break;
Index: src/wp-admin/update.php
===================================================================
--- src/wp-admin/update.php	(revision 34051)
+++ src/wp-admin/update.php	(working copy)
@@ -17,7 +17,7 @@
 if ( isset($_GET['action']) ) {
 	$plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
 	$theme = isset($_REQUEST['theme']) ? urldecode($_REQUEST['theme']) : '';
-	$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
+	$action = wp_validate_action();
 
 	if ( 'update-selected' == $action ) {
 		if ( ! current_user_can( 'update_plugins' ) )
Index: src/wp-admin/user-new.php
===================================================================
--- src/wp-admin/user-new.php	(revision 34051)
+++ src/wp-admin/user-new.php	(working copy)
@@ -29,7 +29,7 @@
 	add_filter( 'wpmu_signup_user_notification_email', 'admin_created_user_email' );
 }
 
-if ( isset($_REQUEST['action']) && 'adduser' == $_REQUEST['action'] ) {
+if ( wp_validate_action( 'adduser' ) ) {
 	check_admin_referer( 'add-user', '_wpnonce_add-user' );
 
 	$user_details = null;
@@ -101,7 +101,7 @@
 	}
 	wp_redirect( $redirect );
 	die();
-} elseif ( isset($_REQUEST['action']) && 'createuser' == $_REQUEST['action'] ) {
+} elseif ( wp_validate_action( 'createuser' ) ) {
 	check_admin_referer( 'create-user', '_wpnonce_create-user' );
 
 	if ( ! current_user_can( 'create_users' ) ) {
Index: src/wp-includes/functions.php
===================================================================
--- src/wp-includes/functions.php	(revision 34051)
+++ src/wp-includes/functions.php	(working copy)
@@ -4980,3 +4980,26 @@
 	</script>
 	<?php
 }
+
+/**
+ * Retrieve and, optionally, validate, an `action` query var
+ *
+ * @since 4.4.0
+ *
+ * @param string $action Optional. Action to validate.
+ * @return string Empty string if there is no action in the request or it doesn't
+ *                match the passed `$action`. Returns the [passed `$action` or
+ *                request action on succcess.
+ */
+function wp_validate_action( $action = '' ) {
+	$r = $_REQUEST;
+	if ( ! isset( $r['action'] ) ) {
+		return '';
+	}
+
+	if ( ! empty( $action ) ) {
+		return $action === $r['action'] ? $action : '';
+	}
+
+	return $r['action'];
+}
\ No newline at end of file
