diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
index 066e4181d6..7a89a594ca 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
@@ -1849,6 +1849,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 			}
 		}
 
+		if ( 'attachment' === $this->post_type ) {
+			return $response;
+		}
+
 		/**
 		 * Filters the post data for a REST API response.
 		 *
diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php
index c023033369..181aaa873b 100644
--- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php
@@ -2154,6 +2154,25 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
 		$this->assertErrorResponse( 'rest_image_not_edited', $response_3, 400 );
 	}
 
+	public function test_rest_prepare_attachment_hook_runs_once() {
+		$attachment_id = $this->factory->attachment->create_object(
+			$this->test_file,
+			0,
+			array(
+				'post_mime_type' => 'image/jpeg',
+				'post_excerpt'   => 'A sample caption',
+			)
+		);
+
+		$filter = new MockAction();
+		add_filter( 'rest_prepare_attachment', array( $filter, 'filter' ) );
+
+		$request = new WP_REST_Request( 'GET', '/wp/v2/media/' . $attachment_id );
+		rest_get_server()->dispatch( $request );
+
+		$this->assertSame( 1, $filter->get_call_count() );
+	}
+
 	/**
 	 * Sets up the mock image editor.
 	 *
