Index: src/wp-admin/network/site-info.php
===================================================================
--- src/wp-admin/network/site-info.php	(revision 28746)
+++ src/wp-admin/network/site-info.php	(working copy)
@@ -49,9 +49,15 @@
 	check_admin_referer( 'edit-site' );
 
 	switch_to_blog( $id );
+	$blog_data = wp_unslash( $_POST['blog'] );
 
+	// remove forward slashes from front and back of the site domain
+	$blog_data['domain'] = trim( $blog_data['domain'], '/' );
+	// ensure one forward slash is present in the front and back of the site path
+	$blog_data['path']   = trailingslashit( '/' . trim( $blog_data['path'], '/' ) );
+
 	if ( isset( $_POST['update_home_url'] ) && $_POST['update_home_url'] == 'update' ) {
-		$blog_address = esc_url_raw( $_POST['blog']['domain'] . $_POST['blog']['path'] );
+		$blog_address = esc_url_raw( $blog_data['domain'] . $blog_data['path'] );
 		if ( get_option( 'siteurl' ) != $blog_address )
 			update_option( 'siteurl', $blog_address );
 
@@ -63,7 +69,6 @@
 	delete_option( 'rewrite_rules' );
 
 	// update blogs table
-	$blog_data = wp_unslash( $_POST['blog'] );
 	$existing_details = get_blog_details( $id, false );
 	$blog_data_checkboxes = array( 'public', 'archived', 'spam', 'mature', 'deleted' );
 	foreach ( $blog_data_checkboxes as $c ) {
Index: tests/phpunit/tests/ms.php
===================================================================
--- tests/phpunit/tests/ms.php	(revision 28742)
+++ tests/phpunit/tests/ms.php	(working copy)
@@ -618,6 +618,40 @@
 	}
 
 	/**
+	 * Check the path for a sub-directory site is correctly sanitised,
+	 * and has a trailing slash.
+	 *
+	 * @ticket 18117
+	 */
+	function test_update_blog_sanitises_subdirectory_path() {
+		global $test_action_counter;
+
+		$user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
+		$blog_id = $this->factory->blog->create( array( 'user_id' => $user_id, 'path' => '/test_blogpath', 'title' => 'Test Title' ) );
+		$this->assertInternalType( 'int', $blog_id );
+
+		$result = update_blog_details( $blog_id, array('domain' => 'example.com', 'path' => 'my_path') );
+
+		$blog = get_blog_details( $blog_id );
+		$this->assertEquals( '/my_path/', $blog->path );
+
+		$result = update_blog_details( $blog_id, array('domain' => 'example.com', 'path' => 'my_path//') );
+
+		$blog = get_blog_details( $blog_id );
+		$this->assertEquals( '/my_path/', $blog->path );
+
+		$result = update_blog_details( $blog_id, array('domain' => 'example.com', 'path' => '//my_path') );
+
+		$blog = get_blog_details( $blog_id );
+		$this->assertEquals( '/my_path/', $blog->path );
+
+		$result = update_blog_details( $blog_id, array('domain' => 'example.com', 'path' => '/my_path') );
+
+		$blog = get_blog_details( $blog_id );
+		$this->assertEquals( '/my_path/', $blog->path );
+	}
+
+	/**
 	 * Test fetching a blog that doesn't exist and again after it exists.
 	 *
 	 * @ticket 23405
