Index: src/wp-admin/js/customize-nav-menus.js
===================================================================
--- src/wp-admin/js/customize-nav-menus.js	(revision 39494)
+++ src/wp-admin/js/customize-nav-menus.js	(working copy)
@@ -536,16 +536,27 @@
 		submitLink: function() {
 			var menuItem,
 				itemName = $( '#custom-menu-item-name' ),
-				itemUrl = $( '#custom-menu-item-url' );
+				itemUrl = $( '#custom-menu-item-url' ),
+				testRegex;
 
 			if ( ! this.currentMenuControl ) {
 				return;
 			}
 
+			// Copyright (c) 2010-2013 Diego Perini, MIT licensed
+			// https://gist.github.com/dperini/729294
+			// see also https://mathiasbynens.be/demo/url-regex
+			// modified to allow protocol-relative URLs
+
+			testRegex = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
+
 			if ( '' === itemName.val() ) {
 				itemName.addClass( 'invalid' );
 				return;
-			} else if ( '' === itemUrl.val() || 'http://' === itemUrl.val() ) {
+			} else if ( '' === itemUrl.val() ||
+				'http://' === itemUrl.val() ||
+				! testRegex.test( itemUrl.val() )
+			) {
 				itemUrl.addClass( 'invalid' );
 				return;
 			}
Index: src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php
===================================================================
--- src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php	(revision 39494)
+++ src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php	(working copy)
@@ -722,7 +722,12 @@
 		$menu_item_value['attr_title'] = wp_unslash( apply_filters( 'excerpt_save_pre', wp_slash( $menu_item_value['attr_title'] ) ) );
 		$menu_item_value['description'] = wp_unslash( apply_filters( 'content_save_pre', wp_slash( $menu_item_value['description'] ) ) );
 
-		$menu_item_value['url'] = esc_url_raw( $menu_item_value['url'] );
+		if ( '' !== $menu_item_value['url'] ) {
+			$menu_item_value['url'] = esc_url_raw( $menu_item_value['url'] );
+			if ( '' === $menu_item_value['url'] ) {
+				return new WP_Error( 'invalid_nav_menu_url', __( 'Invalid URL.' ) ); // Fail sanitization if URL is invalid.
+			}
+		}
 		if ( 'publish' !== $menu_item_value['status'] ) {
 			$menu_item_value['status'] = 'draft';
 		}
Index: tests/phpunit/tests/customize/nav-menu-item-setting.php
===================================================================
--- tests/phpunit/tests/customize/nav-menu-item-setting.php	(revision 39494)
+++ tests/phpunit/tests/customize/nav-menu-item-setting.php	(working copy)
@@ -472,6 +472,9 @@
 		$this->assertNull( $setting->sanitize( 'not an array' ) );
 		$this->assertNull( $setting->sanitize( 123 ) );
 
+		$url_setting = $setting->sanitize( array( 'url' => 'javascript:alert(1)' ) );
+		$this->assertInstanceOf( 'WP_Error', $url_setting );
+
 		$unsanitized = array(
 			'object_id' => 'bad',
 			'object' => '<b>hello</b>',
@@ -479,7 +482,7 @@
 			'position' => -123,
 			'type' => 'custom<b>',
 			'title' => '\o/ o\'o Hi<script>unfilteredHtml()</script>',
-			'url' => 'javascript:alert(1)',
+			'url' => '',
 			'target' => '" onclick="',
 			'attr_title' => '\o/ o\'o <b>bolded</b><script>unfilteredHtml()</script>',
 			'description' => '\o/ o\'o <b>Hello world</b><script>unfilteredHtml()</script>',
