Enable library validation on the Web Content service
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Jan 2018 23:30:23 +0000 (23:30 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Jan 2018 23:30:23 +0000 (23:30 +0000)
Part 1 of https://bugs.webkit.org/show_bug.cgi?id=172365
<rdar://problem/26470661>

Reviewed by David Kilzer.

This makes the Web Content process signed with the Library Validation flag in production
builds. Because doing so would prevent engineering builds of Apple apps that use an
injected bundle from working, this also adds a Development version of the service, which
does not enforce Library Validation. The UI process chooses to use the Development service
iff it would need to load an injected bundle that is not part of the OS.

* Configurations/DebugRelease.xcconfig: Disable Library Validation in engineering builds.

* Configurations/WebContentService.Development.xcconfig: Added. Like the normal service, but
  only installed when WebKit is installed in the OS, and uses a Development variant.

* Configurations/WebContentService.xcconfig: For the Development variant, append
  ".Development" to the product name, which is also the service identifier. Enable Library
  Validation for the Normal variant of the service when WK_LIBRARY_VALIDATION_ENABLED allows
  it.

* UIProcess/Launcher/ProcessLauncher.h: Add nonValidInjectedCodeAllowed member to
  LaunchOptions, false by default.

* UIProcess/Launcher/mac/ProcessLauncherMac.mm:
(WebKit::serviceName): Use the Development variant if nonValidInjectedCodeAllowed is true.

* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::getLaunchOptions): Initialize nonValidInjectedCodeAllowed using
   the new shouldAllowNonValidInjectedCode().
(WebKit::WebProcessProxy::shouldAllowNonValidInjectedCode const): Generic implementation
  that returns false.
* UIProcess/WebProcessProxy.h: Declared shouldAllowNonValidInjectedCode.
* UIProcess/mac/WebProcessProxyMac.mm:
(WebKit::WebProcessProxy::shouldAllowNonValidInjectedCode const): Return true if this is
  system WebKit with a non-system injected bundle.

* WebKit.xcodeproj/project.pbxproj: Added new service target.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@227582 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/Configurations/DebugRelease.xcconfig
Source/WebKit/Configurations/WebContentService.Development.xcconfig [new file with mode: 0644]
Source/WebKit/Configurations/WebContentService.xcconfig
Source/WebKit/UIProcess/Launcher/ProcessLauncher.h
Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm
Source/WebKit/UIProcess/WebProcessProxy.cpp
Source/WebKit/UIProcess/WebProcessProxy.h
Source/WebKit/UIProcess/mac/WebProcessProxyMac.mm
Source/WebKit/WebKit.xcodeproj/project.pbxproj

index 006010b71f10929484ec1c601bf7567352a0aac6..62512b88d668e01f9c01054e1dd8c20c52131e0b 100644 (file)
@@ -1,3 +1,45 @@
+2018-01-24  Dan Bernstein  <mitz@apple.com>
+
+        Enable library validation on the Web Content service
+        Part 1 of https://bugs.webkit.org/show_bug.cgi?id=172365
+        <rdar://problem/26470661>
+
+        Reviewed by David Kilzer.
+
+        This makes the Web Content process signed with the Library Validation flag in production
+        builds. Because doing so would prevent engineering builds of Apple apps that use an
+        injected bundle from working, this also adds a Development version of the service, which
+        does not enforce Library Validation. The UI process chooses to use the Development service
+        iff it would need to load an injected bundle that is not part of the OS.
+
+        * Configurations/DebugRelease.xcconfig: Disable Library Validation in engineering builds.
+
+        * Configurations/WebContentService.Development.xcconfig: Added. Like the normal service, but
+          only installed when WebKit is installed in the OS, and uses a Development variant.
+
+        * Configurations/WebContentService.xcconfig: For the Development variant, append
+          ".Development" to the product name, which is also the service identifier. Enable Library
+          Validation for the Normal variant of the service when WK_LIBRARY_VALIDATION_ENABLED allows
+          it.
+
+        * UIProcess/Launcher/ProcessLauncher.h: Add nonValidInjectedCodeAllowed member to
+          LaunchOptions, false by default.
+
+        * UIProcess/Launcher/mac/ProcessLauncherMac.mm:
+        (WebKit::serviceName): Use the Development variant if nonValidInjectedCodeAllowed is true.
+
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::getLaunchOptions): Initialize nonValidInjectedCodeAllowed using
+           the new shouldAllowNonValidInjectedCode().
+        (WebKit::WebProcessProxy::shouldAllowNonValidInjectedCode const): Generic implementation
+          that returns false.
+        * UIProcess/WebProcessProxy.h: Declared shouldAllowNonValidInjectedCode.
+        * UIProcess/mac/WebProcessProxyMac.mm:
+        (WebKit::WebProcessProxy::shouldAllowNonValidInjectedCode const): Return true if this is
+          system WebKit with a non-system injected bundle.
+
+        * WebKit.xcodeproj/project.pbxproj: Added new service target.
+
 2018-01-24  Chris Dumez  <cdumez@apple.com>
 
         Add a IPC::SendSyncOption indicating we should not process incoming IPC while waiting for the sync reply
index b9f9bc2be5e62f0db8330247e30c24bf2eec834e..f3eee6dd7696bfdcaf7204043bd8f883e2eafbe4 100644 (file)
@@ -47,6 +47,7 @@ WK_RELOCATABLE_FRAMEWORKS = YES;
 WK_XPC_SERVICE_SUFFIX[sdk=macosx*] = .Development;
 WK_XPC_SERVICE_SUFFIX[sdk=*simulator*] = .Development;
 
+WK_LIBRARY_VALIDATION_ENABLED = NO;
 WK_WEBCONTENT_SERVICE_NEEDS_XPC_DOMAIN_EXTENSION_ENTITLEMENT = NO;
 WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG[sdk=macosx*] = YES;
 
diff --git a/Source/WebKit/Configurations/WebContentService.Development.xcconfig b/Source/WebKit/Configurations/WebContentService.Development.xcconfig
new file mode 100644 (file)
index 0000000..3825c26
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) 2018 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+
+#include "WebContentService.xcconfig"
+
+SKIP_INSTALL = YES;
+SKIP_INSTALL[sdk=macosx*] = $(WK_RELOCATABLE_FRAMEWORKS);
+
+WK_XPC_SERVICE_VARIANT = Development;
index 74fe3c5c40995b8c310b6d4fc9ea37a61115ff61..eb5ec1720e40c207d85e081b08469717cabbe89a 100644 (file)
@@ -27,9 +27,13 @@ WK_XPC_SERVICE_IOS_ENTITLEMENTS_BASE = WebContent-iOS;
 
 CODE_SIGN_ENTITLEMENTS[sdk=macosx*] = $(CODE_SIGN_ENTITLEMENTS_OSX_WITH_XPC_DOMAIN_EXTENSION_$(WK_WEBCONTENT_SERVICE_NEEDS_XPC_DOMAIN_EXTENSION_ENTITLEMENT));
 CODE_SIGN_ENTITLEMENTS_OSX_WITH_XPC_DOMAIN_EXTENSION_YES = Configurations/WebContent-OSX.entitlements;
-OTHER_CODE_SIGN_FLAGS[sdk=macosx*] = $(WK_XPC_DOMAIN_EXTENSION_CODE_SIGN_FLAGS);
+OTHER_CODE_SIGN_FLAGS[sdk=macosx*] = $(WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS);
+
+PRODUCT_NAME = $(PRODUCT_NAME_$(WK_XPC_SERVICE_VARIANT));
+PRODUCT_NAME_ = $(PRODUCT_NAME_Normal);
+PRODUCT_NAME_Normal = com.apple.WebKit.WebContent;
+PRODUCT_NAME_Development = com.apple.WebKit.WebContent.Development;
 
-PRODUCT_NAME = com.apple.WebKit.WebContent;
 PRODUCT_BUNDLE_IDENTIFIER = $(PRODUCT_NAME);
 INFOPLIST_FILE[sdk=iphone*] = WebProcess/EntryPoint/mac/XPCService/WebContentService/Info-iOS.plist;
 INFOPLIST_FILE[sdk=macosx*] = WebProcess/EntryPoint/mac/XPCService/WebContentService/Info-OSX.plist;
@@ -42,13 +46,20 @@ WK_WEBCONTENT_SERVICE_NEEDS_XPC_DOMAIN_EXTENSION_ENTITLEMENT_ = $(WK_WEBCONTENT_
 WK_WEBCONTENT_SERVICE_NEEDS_XPC_DOMAIN_EXTENSION_ENTITLEMENT_NO = $(WK_WEBCONTENT_SERVICE_NEEDS_XPC_DOMAIN_EXTENSION_ENTITLEMENT);
 WK_WEBCONTENT_SERVICE_NEEDS_XPC_DOMAIN_EXTENSION_ENTITLEMENT_YES = $(WK_RELOCATABLE_FRAMEWORKS);
 
+WK_LIBRARY_VALIDATION_ENABLED = $(WK_LIBRARY_VALIDATION_ENABLED_$(WK_EMPTY_$(WK_LIBRARY_VALIDATION_ENABLED)));
+WK_LIBRARY_VALIDATION_ENABLED_ = $(WK_LIBRARY_VALIDATION_ENABLED_NO);
+WK_LIBRARY_VALIDATION_ENABLED_NO = $(WK_LIBRARY_VALIDATION_ENABLED);
+WK_LIBRARY_VALIDATION_ENABLED_YES = YES;
+
 WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG = $(WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG_$(WK_EMPTY_$(WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG)));
 WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG_ = $(WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG_NO);
 WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG_NO = $(WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG);
 WK_WEBCONTENT_SERVICE_NEEDS_VERSIONED_FRAMEWORK_PATH_LDFLAG_YES = $(USE_STAGING_INSTALL_PATH);
 
-WK_XPC_DOMAIN_EXTENSION_CODE_SIGN_FLAGS = $(WK_XPC_DOMAIN_EXTENSION_CODE_SIGN_FLAGS_$(WK_WEBCONTENT_SERVICE_NEEDS_XPC_DOMAIN_EXTENSION_ENTITLEMENT));
-WK_XPC_DOMAIN_EXTENSION_CODE_SIGN_FLAGS_YES = -o library;
+WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS = $(WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS_$(WK_XPC_SERVICE_VARIANT));
+WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS_ = $(WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS_Normal);
+WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS_Normal = $(WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS_$(WK_LIBRARY_VALIDATION_ENABLED));
+WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS_YES = -o library;
 
 RUNLOOP_TYPE[sdk=macosx*] = NSRunLoop;
 RUNLOOP_TYPE[sdk=macosx10.13*] = _NSApplicationMain;
index 30bebf3ddaba53b9bfeb7f93feb6381cf5df53f8..de4635cd736d8fef1b73032d6865228652d075fb 100644 (file)
@@ -60,6 +60,7 @@ public:
         ProcessType processType;
         WebCore::ProcessIdentifier processIdentifier;
         HashMap<String, String> extraInitializationData;
+        bool nonValidInjectedCodeAllowed { false };
 
 #if ENABLE(DEVELOPER_MODE) && (PLATFORM(GTK) || PLATFORM(WPE))
         String processCmdPrefix;
index f8420f6c07603226c9d2641802acc8c42ff41266..6d346273b7495eec0c77e3c7793e085dfd5c47c9 100644 (file)
@@ -51,7 +51,7 @@ static const char* serviceName(const ProcessLauncher::LaunchOptions& launchOptio
 {
     switch (launchOptions.processType) {
     case ProcessLauncher::ProcessType::Web:
-        return "com.apple.WebKit.WebContent";
+        return launchOptions.nonValidInjectedCodeAllowed ? "com.apple.WebKit.WebContent.Development" : "com.apple.WebKit.WebContent";
     case ProcessLauncher::ProcessType::Network:
         return "com.apple.WebKit.Networking";
     case ProcessLauncher::ProcessType::Storage:
index 4bb9ce5c06b86ef7d05efd96465d965af7acb129..0451561270da3353197127c2bcd57a5517d7e2cd 100644 (file)
@@ -167,6 +167,8 @@ void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOpt
         }
         launchOptions.extraInitializationData.add(ASCIILiteral("OverrideLanguages"), languageString.toString());
     }
+
+    launchOptions.nonValidInjectedCodeAllowed = shouldAllowNonValidInjectedCode();
 }
 
 void WebProcessProxy::connectionWillOpen(IPC::Connection& connection)
@@ -610,6 +612,13 @@ bool WebProcessProxy::platformIsBeingDebugged() const
 }
 #endif
 
+#if !PLATFORM(MAC)
+bool WebProcessProxy::shouldAllowNonValidInjectedCode() const
+{
+    return false;
+}
+#endif
+
 void WebProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
 {
     if (dispatchMessage(connection, decoder))
index f9d849e389411e475c96e06449dca7a6b9d7b5ad..3701f7b79a559cb14dd2d9a5bc60836355004cff 100644 (file)
@@ -247,6 +247,7 @@ private:
     void getStorageProcessConnection(PAL::SessionID initialSessionID, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&&);
 
     bool platformIsBeingDebugged() const;
+    bool shouldAllowNonValidInjectedCode() const;
 
     static const HashSet<String>& platformPathsWithAssumedReadAccess();
 
index 212623b7aeb175e8bf81314763c697e7b56e14da..d917ad0ea4f3ca41931467bad3b8f7ff7d576a93 100644 (file)
@@ -24,6 +24,7 @@
  */
  
 #import "config.h"
+#import "WebProcessPool.h"
 #import "WebProcessProxy.h"
 
 #if PLATFORM(MAC)
@@ -37,6 +38,24 @@ bool WebProcessProxy::fullKeyboardAccessEnabled()
     return [WKFullKeyboardAccessWatcher fullKeyboardAccessEnabled];
 }
 
+bool WebProcessProxy::shouldAllowNonValidInjectedCode() const
+{
+    static bool isSystemWebKit = [] {
+#if WK_API_ENABLED
+        NSBundle *webkit2Bundle = [NSBundle bundleForClass:NSClassFromString(@"WKWebView")];
+#else
+        NSBundle *webkit2Bundle = [NSBundle bundleForClass:NSClassFromString(@"WKView")];
+#endif
+        return [webkit2Bundle.bundlePath hasPrefix:@"/System/"];
+    }();
+
+    if (!isSystemWebKit)
+        return false;
+
+    const String& path = m_processPool->configuration().injectedBundlePath();
+    return !path.isEmpty() && !path.startsWith("/System/");
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(MAC)
index de54a0cfbf414ccb653dab142c1644ab22ed302b..6b9c9ce80a5287cd89c9543f327a53b53dfdc82a 100644 (file)
@@ -16,6 +16,7 @@
                        );
                        dependencies = (
                                BCA8D46815BCE0D6009DC1F1 /* PBXTargetDependency */,
+                               372EBB492017E6CF00085064 /* PBXTargetDependency */,
                                51A60B2E180CCF1700F3BF50 /* PBXTargetDependency */,
                                BC77F95616D0459100F8F78A /* PBXTargetDependency */,
                                BC82844616B4FF6600A278FE /* PBXTargetDependency */,
                371E695B1AED7A6700495E48 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* WebKit.framework */; };
                372CAF0B1833FD910040AC27 /* WKNSError.h in Headers */ = {isa = PBXBuildFile; fileRef = 372CAF091833FD910040AC27 /* WKNSError.h */; };
                372CAF0C1833FD910040AC27 /* WKNSError.mm in Sources */ = {isa = PBXBuildFile; fileRef = 372CAF0A1833FD910040AC27 /* WKNSError.mm */; };
+               372EBB3C2017E64300085064 /* XPCServiceMain.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC82839616B47EC400A278FE /* XPCServiceMain.mm */; };
+               372EBB3E2017E64300085064 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC3DE46815A91763008D26FC /* Foundation.framework */; };
+               372EBB3F2017E64300085064 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* WebKit.framework */; };
+               372EBB412017E64300085064 /* WebContentProcess.xib in Resources */ = {isa = PBXBuildFile; fileRef = E1D26A4C1759634E0095BFD1 /* WebContentProcess.xib */; };
                373CEAD5185417AE008C363D /* WKNSData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 373CEAD3185417AE008C363D /* WKNSData.mm */; };
                373CEAD6185417AE008C363D /* WKNSData.h in Headers */ = {isa = PBXBuildFile; fileRef = 373CEAD4185417AE008C363D /* WKNSData.h */; };
                373CEAD81859553F008C363D /* WKPagePolicyClientInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 373CEAD71859553F008C363D /* WKPagePolicyClientInternal.h */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+               372EBB3A2017E64300085064 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
+                       remoteInfo = WebKit;
+               };
+               372EBB482017E6CF00085064 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 372EBB382017E64300085064;
+                       remoteInfo = WebContent.Development;
+               };
                375E0626191EA8CC004E3CAF /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
                371A19401824D29300F32A5E /* WKNSDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKNSDictionary.h; sourceTree = "<group>"; };
                372CAF091833FD910040AC27 /* WKNSError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKNSError.h; sourceTree = "<group>"; };
                372CAF0A1833FD910040AC27 /* WKNSError.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKNSError.mm; sourceTree = "<group>"; };
+               372EBB462017E64300085064 /* com.apple.WebKit.WebContent.Development.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = com.apple.WebKit.WebContent.Development.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
+               372EBB4A2017E76000085064 /* WebContentService.Development.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = WebContentService.Development.xcconfig; sourceTree = "<group>"; };
                373CEAD3185417AE008C363D /* WKNSData.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKNSData.mm; sourceTree = "<group>"; };
                373CEAD4185417AE008C363D /* WKNSData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKNSData.h; sourceTree = "<group>"; };
                373CEAD71859553F008C363D /* WKPagePolicyClientInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPagePolicyClientInternal.h; sourceTree = "<group>"; };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               372EBB3D2017E64300085064 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               372EBB3E2017E64300085064 /* Foundation.framework in Frameworks */,
+                               372EBB3F2017E64300085064 /* WebKit.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                510031EE1379CACB00C8DFE4 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                                510031F61379CACB00C8DFE4 /* SecItemShim.dylib */,
                                8DC2EF5B0486A6940098B216 /* WebKit.framework */,
                                CDC3830617211799008A2FC3 /* WebProcessShim.dylib */,
+                               372EBB462017E64300085064 /* com.apple.WebKit.WebContent.Development.xpc */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                                7C0BB9A818DCDE890006C086 /* WebContent-iOS.entitlements */,
                                37B418EB1C9624F20031E63B /* WebContent-OSX.entitlements */,
                                BCACC40E16B0B8A800B6E092 /* WebContentService.xcconfig */,
+                               372EBB4A2017E76000085064 /* WebContentService.Development.xcconfig */,
                                BCB86F4B116AAACD00CE20B7 /* WebKit.xcconfig */,
                                A1EDD2DD1884B9E300BBFE98 /* WebProcessShim.xcconfig */,
                        );
                        productReference = 1AC25FB012A48EA700BD2671 /* PluginProcessShim.dylib */;
                        productType = "com.apple.product-type.library.dynamic";
                };
+               372EBB382017E64300085064 /* WebContent.Development */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 372EBB422017E64300085064 /* Build configuration list for PBXNativeTarget "WebContent.Development" */;
+                       buildPhases = (
+                               372EBB3B2017E64300085064 /* Sources */,
+                               372EBB3D2017E64300085064 /* Frameworks */,
+                               372EBB402017E64300085064 /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               372EBB392017E64300085064 /* PBXTargetDependency */,
+                       );
+                       name = WebContent.Development;
+                       productName = WebKit2Service;
+                       productReference = 372EBB462017E64300085064 /* com.apple.WebKit.WebContent.Development.xpc */;
+                       productType = "com.apple.product-type.xpc-service";
+               };
                510031EA1379CACB00C8DFE4 /* SecItemShim */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 510031F21379CACB00C8DFE4 /* Build configuration list for PBXNativeTarget "SecItemShim" */;
                                510031EA1379CACB00C8DFE4 /* SecItemShim */,
                                CDC382FB17211799008A2FC3 /* WebProcessShim */,
                                BC3DE46515A91763008D26FC /* WebContent */,
+                               372EBB382017E64300085064 /* WebContent.Development */,
                                BC8283B016B4BF7700A278FE /* Networking */,
                                BC8283F816B4FDDE00A278FE /* Plugin.32 */,
                                BC82841E16B4FDF600A278FE /* Plugin.64 */,
 /* End PBXProject section */
 
 /* Begin PBXResourcesBuildPhase section */
+               372EBB402017E64300085064 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               372EBB412017E64300085064 /* WebContentProcess.xib in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                51F7DC45180CC93600212CA3 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                                "$(BUILT_PRODUCTS_DIR)/com.apple.WebKit.Plugin.32.xpc",
                                "$(BUILT_PRODUCTS_DIR)/com.apple.WebKit.Plugin.64.xpc",
                                "$(BUILT_PRODUCTS_DIR)/$(WK_STORAGE_SERVICE_PRODUCT_NAME).xpc",
+                               "$(BUILT_PRODUCTS_DIR)/com.apple.WebKit.WebContent.Development.xpc",
                        );
                        name = "Copy XPC services for engineering builds";
                        outputPaths = (
                                "$(BUILT_PRODUCTS_DIR)/WebKit.framework/XPCServices/com.apple.WebKit.Plugin.32.xpc",
                                "$(BUILT_PRODUCTS_DIR)/WebKit.framework/XPCServices/com.apple.WebKit.Plugin.64.xpc",
                                "$(BUILT_PRODUCTS_DIR)/WebKit.framework/XPCServices/$(WK_STORAGE_SERVICE_PRODUCT_NAME).xpc",
+                               "$(BUILT_PRODUCTS_DIR)/WebKit.framework/XPCServices/com.apple.WebKit.WebContent.Development.xpc",
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               372EBB3B2017E64300085064 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               372EBB3C2017E64300085064 /* XPCServiceMain.mm in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                510031EC1379CACB00C8DFE4 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+               372EBB392017E64300085064 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 8DC2EF4F0486A6940098B216 /* WebKit */;
+                       targetProxy = 372EBB3A2017E64300085064 /* PBXContainerItemProxy */;
+               };
+               372EBB492017E6CF00085064 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 372EBB382017E64300085064 /* WebContent.Development */;
+                       targetProxy = 372EBB482017E6CF00085064 /* PBXContainerItemProxy */;
+               };
                375E0627191EA8CC004E3CAF /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 8DC2EF4F0486A6940098B216 /* WebKit */;
                        };
                        name = Release;
                };
+               372EBB432017E64300085064 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 372EBB4A2017E76000085064 /* WebContentService.Development.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Debug;
+               };
+               372EBB442017E64300085064 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 372EBB4A2017E76000085064 /* WebContentService.Development.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Release;
+               };
+               372EBB452017E64300085064 /* Production */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 372EBB4A2017E76000085064 /* WebContentService.Development.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Production;
+               };
                510031F31379CACB00C8DFE4 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = A1EDD2DC1884B9B500BBFE98 /* SecItemShim.xcconfig */;
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Production;
                };
+               372EBB422017E64300085064 /* Build configuration list for PBXNativeTarget "WebContent.Development" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               372EBB432017E64300085064 /* Debug */,
+                               372EBB442017E64300085064 /* Release */,
+                               372EBB452017E64300085064 /* Production */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Production;
+               };
                510031F21379CACB00C8DFE4 /* Build configuration list for PBXNativeTarget "SecItemShim" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (