Index: src/wp-includes/kses.php
===================================================================
--- src/wp-includes/kses.php	(revision 43688)
+++ src/wp-includes/kses.php	(working copy)
@@ -1687,15 +1687,13 @@
  * @return string            Filtered string of CSS rules.
  */
 function safecss_filter_attr( $css, $deprecated = '' ) {
-	if ( !empty( $deprecated ) )
+	if ( ! empty( $deprecated ) )
 		_deprecated_argument( __FUNCTION__, '2.8.1' ); // Never implemented
 
-	$css = wp_kses_no_null($css);
-	$css = str_replace(array("\n","\r","\t"), '', $css);
+	$css = wp_kses_no_null( $css );
+	$css = str_replace( array( "\n", "\r", "\t" ), '', $css );
+	$allowed_protocols = wp_allowed_protocols();
 
-	if ( preg_match( '%[\\\\(&=}]|/\*%', $css ) ) // remove any inline css containing \ ( & } = or comments
-		return '';
-
 	$css_array = explode( ';', trim( $css ) );
 
 	/**
@@ -1710,6 +1708,7 @@
 	$allowed_attr = apply_filters( 'safe_style_css', array(
 		'background',
 		'background-color',
+		'background-image',
 
 		'border',
 		'border-width',
@@ -1778,25 +1777,82 @@
 		'list-style-type',
 	) );
 
-	if ( empty($allowed_attr) )
+
+	/*
+	 * CSS attributes that accept URL data types.
+	 *
+	 * This is in accordance to the CSS spec and unrelated to
+	 * the sub-set of supported attributes above.
+	 *
+	 * See: https://developer.mozilla.org/en-US/docs/Web/CSS/url
+	 */
+	$css_url_data_types = array(
+		'background',
+		'background-image',
+
+		'cursor',
+
+		'list-style',
+		'list-style-image',
+	);
+
+	if ( empty( $allowed_attr ) ) {
 		return $css;
+	}
 
 	$css = '';
 	foreach ( $css_array as $css_item ) {
-		if ( $css_item == '' )
+		if ( $css_item == '' ) {
 			continue;
-		$css_item = trim( $css_item );
-		$found = false;
+		}
+
+		$css_item        = trim( $css_item );
+		$css_test_string = $css_item;
+		$found           = false;
+		$url_attr        = false;
+
 		if ( strpos( $css_item, ':' ) === false ) {
 			$found = true;
 		} else {
-			$parts = explode( ':', $css_item );
-			if ( in_array( trim( $parts[0] ), $allowed_attr ) )
+			$parts = explode( ':', $css_item, 2 );
+			$css_selector = trim( $parts[0] );
+
+			if ( in_array( $css_selector, $allowed_attr, true ) ) {
 				$found = true;
+				$url_attr = in_array( $css_selector, $css_url_data_types, true );
+			}
 		}
-		if ( $found ) {
-			if( $css != '' )
+
+		if ( $found && $url_attr ) {
+			// Simplified: matches the sequence `url(*)`.
+			preg_match_all( '/url\([^)]+\)/', $parts[1], $url_matches );
+
+			foreach ( $url_matches[0] as $url_match ) {
+				// Clean up the URL from each of the matches above.
+				preg_match( '/^url\(\s*([\'\"]?)(.*)(\g1)\s*\)$/', $url_match, $url_pieces );
+
+				if ( empty( $url_pieces[2] ) ) {
+					$found = false;
+					break;
+				}
+
+				$url = trim( $url_pieces[2] );
+
+				if ( empty( $url ) || $url !== wp_kses_bad_protocol( $url, $allowed_protocols ) ) {
+					$found = false;
+					break;
+				} else {
+					// Remove the whole `url(*)` bit that was matched above from the CSS.
+					$css_test_string = str_replace( $url_match, '', $css_test_string );
+				}
+			}
+		}
+
+		if ( $found && ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string ) ) {
+			if ( $css != '' ) {
 				$css .= ';';
+			}
+
 			$css .= $css_item;
 		}
 	}
Index: tests/phpunit/tests/kses.php
===================================================================
--- tests/phpunit/tests/kses.php	(revision 43688)
+++ tests/phpunit/tests/kses.php	(working copy)
@@ -718,4 +718,151 @@
 
 		$this->assertEquals( "<{$element}>", wp_kses_attr( $element, $attribute, array( 'foo' => false ), array() ) );
 	}
+
+	/**
+	 * Test URL sanitization in the style tag.
+	 *
+	 * @dataProvider data_kses_style_attr_with_url
+	 *
+	 * @ticket 45067
+	 *
+	 * @param $input string The style attribute saved in the editor.
+	 * @param $expected string The sanitized style attribute.
+	 */
+	function test_kses_style_attr_with_url( $input, $expected ) {
+		$actual = safecss_filter_attr( $input );
+
+		$this->assertSame( $expected, $actual );
+	}
+
+	/**
+	 * Data provider testing style attribute sanitization.
+	 *
+	 * @return array Nested array of input, expected pairs.
+	 */
+	function data_kses_style_attr_with_url() {
+		return array(
+			/*
+			 * Valid use cases.
+			 */
+
+			// Double quotes.
+			array(
+				'background-image: url( "http://example.com/valid.gif" );',
+				'background-image: url( "http://example.com/valid.gif" )',
+			),
+
+			// Single quotes.
+			array(
+				"background-image: url( 'http://example.com/valid.gif' );",
+				"background-image: url( 'http://example.com/valid.gif' )",
+			),
+
+			// No quotes.
+			array(
+				'background-image: url( http://example.com/valid.gif );',
+				'background-image: url( http://example.com/valid.gif )',
+			),
+
+			// Single quotes, extra spaces.
+			array(
+				"background-image: url( '  http://example.com/valid.gif ' );",
+				"background-image: url( '  http://example.com/valid.gif ' )",
+			),
+
+			// Line breaks, single quotes.
+			array(
+				"background-image: url(\n'http://example.com/valid.gif' );",
+				"background-image: url('http://example.com/valid.gif' )",
+			),
+
+			// Tabs not spaces, single quotes.
+			array(
+				"background-image: url(\t'http://example.com/valid.gif'\t\t);",
+				"background-image: url('http://example.com/valid.gif')",
+			),
+
+			// Single quotes, absolute path.
+			array(
+				"background: url('/valid.gif');",
+				"background: url('/valid.gif')",
+			),
+
+			// Single quotes, relative path.
+			array(
+				"background: url('../wp-content/uploads/2018/10/valid.gif');",
+				"background: url('../wp-content/uploads/2018/10/valid.gif')",
+			),
+
+			// Error check: valid property not containing a URL.
+			array(
+				"background: red",
+				"background: red",
+			),
+
+			/*
+			 * Invalid use cases.
+			 */
+
+			// Attribute doesn't support URL properties.
+			array(
+				'color: url( "http://example.com/invalid.gif" );',
+				'',
+			),
+
+			// Mismatched quotes.
+			array(
+				'background-image: url( "http://example.com/valid.gif\' );',
+				'',
+			),
+
+			// Bad protocol, double quotes.
+			array(
+				'background-image: url( "bad://example.com/invalid.gif" );',
+				'',
+			),
+
+			// Bad protocol, single quotes.
+			array(
+				"background-image: url( 'bad://example.com/invalid.gif' );",
+				'',
+			),
+
+			// Bad protocol, single quotes.
+			array(
+				"background-image: url( 'bad://example.com/invalid.gif' );",
+				'',
+			),
+
+			// Bad protocol, single quotes, strange spacing.
+			array(
+				"background-image: url( '  \tbad://example.com/invalid.gif ' );",
+				'',
+			),
+
+			// Bad protocol, no quotes.
+			array(
+				'background-image: url( bad://example.com/invalid.gif );',
+				'',
+			),
+
+			// No URL inside url().
+			array(
+				'background-image: url();',
+				'',
+			),
+
+			// Malformed, no closing `)`.
+			array(
+				'background-image: url( "http://example.com" ;',
+				'',
+			),
+
+			// Malformed, no closing `"`.
+			array(
+				'background-image: url( "http://example.com );',
+				'',
+			),
+		);
+	}
 }
Index: tests/phpunit/tests/shortcode.php
===================================================================
--- tests/phpunit/tests/shortcode.php	(revision 43688)
+++ tests/phpunit/tests/shortcode.php	(working copy)
@@ -492,8 +492,8 @@
 				'<[gallery]>',
 			),
 			array(
-				'<div style="background:url([[gallery]])">',
-				'<div style="background:url([[gallery]])">',
+				'<div style="selector:url([[gallery]])">',
+				'<div style="selector:url([[gallery]])">',
 			),
 			array(
 				'[gallery]<div>Hello</div>[/gallery]',
