diff --git src/wp-admin/includes/file.php src/wp-admin/includes/file.php
index 60416754f3..158542df53 100644
--- src/wp-admin/includes/file.php
+++ src/wp-admin/includes/file.php
@@ -877,6 +877,9 @@ function _wp_handle_upload( &$file, $overrides, $time, $action ) {
 		$unique_filename_callback = $overrides['unique_filename_callback'];
 	}
 
+	// You may define your own subdirectory and pass the name in $overrides['subdir'].
+	$subdir = isset( $overrides['subdir'] ) ? $overrides['subdir'] : '';
+	
 	/*
 	 * This may not have originally been intended to be overridable,
 	 * but historically has been.
@@ -976,7 +979,7 @@ function _wp_handle_upload( &$file, $overrides, $time, $action ) {
 	 * A writable uploads dir will pass this test. Again, there's no point
 	 * overriding this one.
 	 */
-	$uploads = wp_upload_dir( $time );
+	$uploads = wp_upload_dir( $time, true, false, $subdir );
 	if ( ! ( $uploads && false === $uploads['error'] ) ) {
 		return call_user_func_array( $upload_error_handler, array( &$file, $uploads['error'] ) );
 	}
diff --git src/wp-includes/fonts.php src/wp-includes/fonts.php
index 4806662160..68ded26989 100644
--- src/wp-includes/fonts.php
+++ src/wp-includes/fonts.php
@@ -126,45 +126,7 @@ function wp_get_font_dir() {
  * }
  */
 function wp_font_dir( $create_dir = true ) {
-	/*
-	 * Allow extenders to manipulate the font directory consistently.
-	 *
-	 * Ensures the upload_dir filter is fired both when calling this function
-	 * directly and when the upload directory is filtered in the Font Face
-	 * REST API endpoint.
-	 */
-	add_filter( 'upload_dir', '_wp_filter_font_directory' );
-	$font_dir = wp_upload_dir( null, $create_dir, false );
-	remove_filter( 'upload_dir', '_wp_filter_font_directory' );
-	return $font_dir;
-}
-
-/**
- * A callback function for use in the {@see 'upload_dir'} filter.
- *
- * This function is intended for internal use only and should not be used by plugins and themes.
- * Use wp_get_font_dir() instead.
- *
- * @since 6.5.0
- * @access private
- *
- * @param string $font_dir The font directory.
- * @return string The modified font directory.
- */
-function _wp_filter_font_directory( $font_dir ) {
-	if ( doing_filter( 'font_dir' ) ) {
-		// Avoid an infinite loop.
-		return $font_dir;
-	}
-
-	$font_dir = array(
-		'path'    => untrailingslashit( $font_dir['basedir'] ) . '/fonts',
-		'url'     => untrailingslashit( $font_dir['baseurl'] ) . '/fonts',
-		'subdir'  => '',
-		'basedir' => untrailingslashit( $font_dir['basedir'] ) . '/fonts',
-		'baseurl' => untrailingslashit( $font_dir['baseurl'] ) . '/fonts',
-		'error'   => false,
-	);
+	$font_dir = wp_upload_dir( null, $create_dir, false, '/fonts' );
 
 	/**
 	 * Filters the fonts directory data.
diff --git src/wp-includes/functions.php src/wp-includes/functions.php
index b85036cb95..4d703e2963 100644
--- src/wp-includes/functions.php
+++ src/wp-includes/functions.php
@@ -2348,6 +2348,7 @@ function wp_get_upload_dir() {
  * @param bool   $create_dir Optional. Whether to check and create the uploads directory.
  *                           Default true for backward compatibility.
  * @param bool   $refresh_cache Optional. Whether to refresh the cache. Default false.
+ * @param string $subdir Optional. Sub directories to override default time formatted in 'yyyy/mm'. Default empty.
  * @return array {
  *     Array of information about the upload directory.
  *
@@ -2359,13 +2360,13 @@ function wp_get_upload_dir() {
  *     @type string|false $error   False or error message.
  * }
  */
-function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false ) {
+function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false, $subdir = '' ) {
 	static $cache = array(), $tested_paths = array();
 
 	$key = sprintf( '%d-%s', get_current_blog_id(), (string) $time );
 
 	if ( $refresh_cache || empty( $cache[ $key ] ) ) {
-		$cache[ $key ] = _wp_upload_dir( $time );
+		$cache[ $key ] = _wp_upload_dir( $time, $subdir );
 	}
 
 	/**
diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php
index c7f72d4ec1..8620645cc5 100644
--- src/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php
+++ src/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php
@@ -856,8 +856,6 @@ class WP_REST_Font_Faces_Controller extends WP_REST_Posts_Controller {
 	 */
 	protected function handle_font_file_upload( $file ) {
 		add_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) );
-		// Filter the upload directory to return the fonts directory.
-		add_filter( 'upload_dir', '_wp_filter_font_directory' );
 
 		$overrides = array(
 			'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ),
@@ -865,6 +863,8 @@ class WP_REST_Font_Faces_Controller extends WP_REST_Posts_Controller {
 			'test_form'            => false,
 			// Only allow uploading font files for this request.
 			'mimes'                => WP_Font_Utils::get_allowed_font_mime_types(),
+			// Only allow uploading font files to the fonts directory.
+			'subdir'               => '/fonts'
 		);
 
 		// Bypasses is_uploaded_file() when running unit tests.
@@ -874,7 +874,6 @@ class WP_REST_Font_Faces_Controller extends WP_REST_Posts_Controller {
 
 		$uploaded_file = wp_handle_upload( $file, $overrides );
 
-		remove_filter( 'upload_dir', '_wp_filter_font_directory' );
 		remove_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) );
 
 		return $uploaded_file;
diff --git tests/phpunit/tests/fonts/font-library/wpFontsDir.php tests/phpunit/tests/fonts/font-library/wpFontsDir.php
index 22208ca7b2..005f42a7f7 100644
--- tests/phpunit/tests/fonts/font-library/wpFontsDir.php
+++ tests/phpunit/tests/fonts/font-library/wpFontsDir.php
@@ -117,8 +117,6 @@ class Tests_Fonts_WpFontDir extends WP_UnitTestCase {
 		 * This emulates the approach a plugin developer may take to
 		 * add the filter when extending the font library functionality.
 		 */
-		add_filter( 'upload_dir', '_wp_filter_font_directory' );
-
 		add_filter(
 			'upload_dir',
 			function ( $upload_dir ) {
