Title: [278877] trunk/Source
Revision
278877
Author
bfulg...@apple.com
Date
2021-06-15 09:46:14 -0700 (Tue, 15 Jun 2021)

Log Message

[Cocoa] Harden WebAuthn process by restricting to browser-entitled processes
https://bugs.webkit.org/show_bug.cgi?id=226772
<rdar://problem/74721877>

Reviewed by Darin Adler.

Source/WebKit:

We should ensure that any process attempting to launch the WebAuthn XPC service is entitled as a full web browser. We
should also ensure that the process requesting WebAuthn operations over WebKit CoreIPC is the WebContent process.

Tested by existing WebAuthn tests.

* Platform/Logging.h: Add WebAuthn category.
* Shared/Cocoa/DefaultWebBrowserChecks.mm:
(WebKit::isInWebKitChildProcess): Recognize 'com.apple.WebKit.WebAuthn' as a WebKit sub-process.
* UIProcess/Cocoa/WebProcessProxyCocoa.mm:
(WebKit::WebProcessProxy::hasCorrectPACEntitlement): Added.
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::getWebAuthnProcessConnection): Add a new MESSAGE_CHECK that the process requesting a WebAuthn
process connection is a WebContent process.
* UIProcess/WebProcessProxy.h:
* WebAuthnProcess/WebAuthnProcess.cpp:
(WebKit::WebAuthnProcess::platformInitializeWebAuthnProcess): Add some logging.
* WebAuthnProcess/WebAuthnProcess.h:
* WebAuthnProcess/ios/WebAuthnProcessIOS.mm:
(WebKit::WebAuthnProcess::platformInitializeWebAuthnProcess): Ensure that the application invoking the WebAuthn XPC service
is entitled as a default web browser.
* WebAuthnProcess/mac/WebAuthnProcessMac.mm:
(WebKit::WebAuthnProcess::platformInitializeWebAuthnProcess): Stub.
* WebProcess/WebProcess.cpp:
(WebKit::getWebAuthnProcessConnection):
(WebKit::WebProcess::ensureWebAuthnProcessConnection):

Source/WTF:

Add a new entitlement utility that returns the String value of a given entitlement for
the process with the provided audit token.

* wtf/cocoa/Entitlements.h:
* wtf/cocoa/Entitlements.mm:
(WTF::hasEntitlementValue):
* wtf/PlatformHave.h: Add item for PAC shared region feature.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (278876 => 278877)


--- trunk/Source/WTF/ChangeLog	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WTF/ChangeLog	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,3 +1,19 @@
+2021-06-15  Brent Fulgham  <bfulg...@apple.com>
+
+        [Cocoa] Harden WebAuthn process by restricting to browser-entitled processes
+        https://bugs.webkit.org/show_bug.cgi?id=226772
+        <rdar://problem/74721877>
+
+        Reviewed by Darin Adler.
+
+        Add a new entitlement utility that returns the String value of a given entitlement for
+        the process with the provided audit token.
+
+        * wtf/cocoa/Entitlements.h:
+        * wtf/cocoa/Entitlements.mm:
+        (WTF::hasEntitlementValue):
+        * wtf/PlatformHave.h: Add item for PAC shared region feature.
+
 2021-06-14  Per Arne  <pvol...@apple.com>
 
         [iOS] Sync Accessibility preferences

Modified: trunk/Source/WTF/wtf/PlatformHave.h (278876 => 278877)


--- trunk/Source/WTF/wtf/PlatformHave.h	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WTF/wtf/PlatformHave.h	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1038,3 +1038,7 @@
 #if PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 150000
 #define HAVE_PER_APP_ACCESSIBILITY_PREFERENCES 1
 #endif
+
+#if (PLATFORM(IOS_FAMILY) && !PLATFORM(IOS_FAMILY_SIMULATOR)) || PLATFORM(MACCATALYST) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 110000)
+#define HAVE_PAC_SHARED_REGION_ID 1
+#endif

Modified: trunk/Source/WTF/wtf/cocoa/Entitlements.h (278876 => 278877)


--- trunk/Source/WTF/wtf/cocoa/Entitlements.h	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WTF/wtf/cocoa/Entitlements.h	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,9 +31,12 @@
 
 namespace WTF {
 
+class String;
+
 WTF_EXPORT_PRIVATE bool hasEntitlement(audit_token_t, const char* entitlement);
 WTF_EXPORT_PRIVATE bool hasEntitlement(xpc_connection_t, const char* entitlement);
 WTF_EXPORT_PRIVATE bool processHasEntitlement(const char* entitlement);
+WTF_EXPORT_PRIVATE bool hasEntitlementValue(audit_token_t, const char* entitlement, const char* value);
 
 } // namespace WTF
 

Modified: trunk/Source/WTF/wtf/cocoa/Entitlements.mm (278876 => 278877)


--- trunk/Source/WTF/wtf/cocoa/Entitlements.mm	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WTF/wtf/cocoa/Entitlements.mm	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,9 @@
 
 #import <wtf/OSObjectPtr.h>
 #import <wtf/RetainPtr.h>
+#import <wtf/cf/TypeCastsCF.h>
 #import <wtf/spi/cocoa/SecuritySPI.h>
+#import <wtf/text/WTFString.h>
 
 namespace WTF {
 
@@ -57,4 +59,15 @@
     return hasEntitlement(adoptCF(SecTaskCreateFromSelf(kCFAllocatorDefault)).get(), entitlement);
 }
 
+bool hasEntitlementValue(audit_token_t token, const char* entitlement, const char* value)
+{
+    auto secTaskForToken = adoptCF(SecTaskCreateWithAuditToken(kCFAllocatorDefault, token));
+    if (!secTaskForToken)
+        return { };
+
+    auto string = adoptCF(CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, entitlement, kCFStringEncodingASCII, kCFAllocatorNull));
+    String entitlementValue = dynamic_cf_cast<CFStringRef>(adoptCF(SecTaskCopyValueForEntitlement(secTaskForToken.get(), string.get(), nullptr)).get());
+    return entitlementValue == value;
+}
+
 } // namespace WTF

Modified: trunk/Source/WebKit/ChangeLog (278876 => 278877)


--- trunk/Source/WebKit/ChangeLog	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/ChangeLog	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,3 +1,37 @@
+2021-06-15  Brent Fulgham  <bfulg...@apple.com>
+
+        [Cocoa] Harden WebAuthn process by restricting to browser-entitled processes
+        https://bugs.webkit.org/show_bug.cgi?id=226772
+        <rdar://problem/74721877>
+
+        Reviewed by Darin Adler.
+
+        We should ensure that any process attempting to launch the WebAuthn XPC service is entitled as a full web browser. We
+        should also ensure that the process requesting WebAuthn operations over WebKit CoreIPC is the WebContent process.
+
+        Tested by existing WebAuthn tests.
+
+        * Platform/Logging.h: Add WebAuthn category.
+        * Shared/Cocoa/DefaultWebBrowserChecks.mm:
+        (WebKit::isInWebKitChildProcess): Recognize 'com.apple.WebKit.WebAuthn' as a WebKit sub-process.
+        * UIProcess/Cocoa/WebProcessProxyCocoa.mm:
+        (WebKit::WebProcessProxy::hasCorrectPACEntitlement): Added.
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::getWebAuthnProcessConnection): Add a new MESSAGE_CHECK that the process requesting a WebAuthn
+        process connection is a WebContent process.
+        * UIProcess/WebProcessProxy.h:
+        * WebAuthnProcess/WebAuthnProcess.cpp:
+        (WebKit::WebAuthnProcess::platformInitializeWebAuthnProcess): Add some logging.
+        * WebAuthnProcess/WebAuthnProcess.h:
+        * WebAuthnProcess/ios/WebAuthnProcessIOS.mm:
+        (WebKit::WebAuthnProcess::platformInitializeWebAuthnProcess): Ensure that the application invoking the WebAuthn XPC service
+        is entitled as a default web browser.
+        * WebAuthnProcess/mac/WebAuthnProcessMac.mm:
+        (WebKit::WebAuthnProcess::platformInitializeWebAuthnProcess): Stub.
+        * WebProcess/WebProcess.cpp:
+        (WebKit::getWebAuthnProcessConnection):
+        (WebKit::WebProcess::ensureWebAuthnProcessConnection):
+
 2021-06-15  Youenn Fablet  <you...@apple.com>
 
         Caches::removeCacheEntry should check for m_storage

Modified: trunk/Source/WebKit/Platform/Logging.h (278876 => 278877)


--- trunk/Source/WebKit/Platform/Logging.h	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/Platform/Logging.h	2021-06-15 16:46:14 UTC (rev 278877)
@@ -101,6 +101,7 @@
     M(ViewportSizing) \
     M(VirtualMemory) \
     M(VisibleRects) \
+    M(WebAuthn) \
     M(WebGL) \
     M(WebRTC) \
     M(WheelEvents) \

Modified: trunk/Source/WebKit/Shared/Cocoa/DefaultWebBrowserChecks.mm (278876 => 278877)


--- trunk/Source/WebKit/Shared/Cocoa/DefaultWebBrowserChecks.mm	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/Shared/Cocoa/DefaultWebBrowserChecks.mm	2021-06-15 16:46:14 UTC (rev 278877)
@@ -76,7 +76,8 @@
         NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
         isInSubProcess = [bundleIdentifier hasPrefix:@"com.apple.WebKit.WebContent"]
             || [bundleIdentifier hasPrefix:@"com.apple.WebKit.Networking"]
-            || [bundleIdentifier hasPrefix:@"com.apple.WebKit.GPU"];
+            || [bundleIdentifier hasPrefix:@"com.apple.WebKit.GPU"]
+            || [bundleIdentifier hasPrefix:@"com.apple.WebKit.WebAuthn"];
     });
 
     return isInSubProcess;

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm (278876 => 278877)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm	2021-06-15 16:46:14 UTC (rev 278877)
@@ -41,6 +41,7 @@
 #import <sys/sysctl.h>
 #import <wtf/NeverDestroyed.h>
 #import <wtf/Scope.h>
+#import <wtf/cocoa/Entitlements.h>
 #import <wtf/cocoa/VectorCocoa.h>
 #import <wtf/spi/darwin/SandboxSPI.h>
 
@@ -298,4 +299,31 @@
     });
 }
 
+bool WebProcessProxy::hasCorrectPACEntitlement()
+{
+    if (!hasConnection()) {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+#if HAVE(PAC_SHARED_REGION_ID)
+    auto auditToken = connection()->getAuditToken();
+    if (!auditToken) {
+        ASSERT_NOT_REACHED();
+        RELEASE_LOG_ERROR(Process, "Unable to get parent web process audit token");
+        return false;
+    }
+
+#if USE(APPLE_INTERNAL_SDK)
+    // Confirm that the connection is from a WebContent process:
+    if (!WTF::hasEntitlementValue(auditToken.value(), "com.apple.pac.shared_region_id", "WebContent")) {
+        RELEASE_LOG_ERROR(Process, "Process is not an entitled WebContent process. Process shared_region_id is incorrect.");
+        return false;
+    }
+#endif
+#endif
+
+    return true;
 }
+
+}

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (278876 => 278877)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -100,6 +100,7 @@
 
 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, connection())
 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(checkURLReceivedFromWebProcess(url), connection())
+#define MESSAGE_CHECK_COMPLETION(assertion, completion) MESSAGE_CHECK_COMPLETION_BASE(assertion, connection(), completion)
 
 namespace WebKit {
 using namespace WebCore;
@@ -800,6 +801,7 @@
 #if ENABLE(WEB_AUTHN)
 void WebProcessProxy::getWebAuthnProcessConnection(Messages::WebProcessProxy::GetWebAuthnProcessConnection::DelayedReply&& reply)
 {
+    MESSAGE_CHECK_COMPLETION(hasCorrectPACEntitlement(), reply({ }));
     m_processPool->getWebAuthnProcessConnection(*this, WTFMove(reply));
 }
 #endif
@@ -1998,3 +2000,4 @@
 
 #undef MESSAGE_CHECK
 #undef MESSAGE_CHECK_URL
+#undef MESSAGE_CHECK_COMPLETION

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (278876 => 278877)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -527,6 +527,10 @@
     void isAXAuthenticated(audit_token_t, CompletionHandler<void(bool)>&&);
 #endif
 
+#if PLATFORM(COCOA)
+    bool hasCorrectPACEntitlement();
+#endif
+
     enum class IsWeak { No, Yes };
     template<typename T> class WeakOrStrongPtr {
     public:

Modified: trunk/Source/WebKit/WebAuthnProcess/WebAuthnProcess.cpp (278876 => 278877)


--- trunk/Source/WebKit/WebAuthnProcess/WebAuthnProcess.cpp	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/WebAuthnProcess/WebAuthnProcess.cpp	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -136,6 +136,12 @@
     static_cast<MockAuthenticatorManager*>(&m_authenticatorManager)->setTestConfiguration(WTFMove(configuration));
 }
 
+#if !PLATFORM(COCOA)
+void WebAuthnProcess::platformInitializeWebAuthnProcess(const WebAuthnProcessCreationParameters&)
+{
+}
+#endif
+
 } // namespace WebKit
 
 #endif // ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebKit/WebAuthnProcess/WebAuthnProcess.h (278876 => 278877)


--- trunk/Source/WebKit/WebAuthnProcess/WebAuthnProcess.h	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/WebAuthnProcess/WebAuthnProcess.h	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -65,6 +65,7 @@
     void setMockWebAuthenticationConfiguration(WebCore::MockWebAuthenticationConfiguration&&);
 
 private:
+    void platformInitializeWebAuthnProcess(const WebAuthnProcessCreationParameters&);
     void lowMemoryHandler(Critical);
 
     // AuxiliaryProcess

Modified: trunk/Source/WebKit/WebAuthnProcess/ios/WebAuthnProcessIOS.mm (278876 => 278877)


--- trunk/Source/WebKit/WebAuthnProcess/ios/WebAuthnProcessIOS.mm	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/WebAuthnProcess/ios/WebAuthnProcessIOS.mm	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
 
 #if ENABLE(WEB_AUTHN) && PLATFORM(IOS_FAMILY)
 
+#import "DefaultWebBrowserChecks.h"
 #import <WebCore/NotImplemented.h>
 #import <WebCore/WebCoreThreadSystemInterface.h>
 
@@ -48,6 +49,11 @@
 {
 }
 
+void WebAuthnProcess::platformInitializeWebAuthnProcess(const WebAuthnProcessCreationParameters& parameters)
+{
+    RELEASE_ASSERT(isParentProcessAFullWebBrowser(*this));
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(WEB_AUTHN) && PLATFORM(IOS_FAMILY)

Modified: trunk/Source/WebKit/WebAuthnProcess/mac/WebAuthnProcessMac.mm (278876 => 278877)


--- trunk/Source/WebKit/WebAuthnProcess/mac/WebAuthnProcessMac.mm	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/WebAuthnProcess/mac/WebAuthnProcessMac.mm	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -66,6 +66,10 @@
     AuxiliaryProcess::initializeSandbox(parameters, sandboxParameters);
 }
 
+void WebAuthnProcess::platformInitializeWebAuthnProcess(const WebAuthnProcessCreationParameters&)
+{
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (278876 => 278877)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2021-06-15 16:41:28 UTC (rev 278876)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2021-06-15 16:46:14 UTC (rev 278877)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1298,8 +1298,10 @@
     if (!connection.sendSync(Messages::WebProcessProxy::GetWebAuthnProcessConnection(), Messages::WebProcessProxy::GetWebAuthnProcessConnection::Reply(connectionInfo), 0)) {
         // If we failed the first time, retry once. The attachment may have become invalid
         // before it was received by the web process if the network process crashed.
-        if (!connection.sendSync(Messages::WebProcessProxy::GetWebAuthnProcessConnection(), Messages::WebProcessProxy::GetWebAuthnProcessConnection::Reply(connectionInfo), 0))
+        if (!connection.sendSync(Messages::WebProcessProxy::GetWebAuthnProcessConnection(), Messages::WebProcessProxy::GetWebAuthnProcessConnection::Reply(connectionInfo), 0)) {
+            RELEASE_LOG_ERROR(WebAuthn, "getWebAuthnProcessConnection: Unable to connect to WebAuthn process (Terminating)");
             CRASH();
+        }
     }
 
     return connectionInfo;
@@ -1318,8 +1320,10 @@
         if (!IPC::Connection::identifierIsValid(connectionInfo.identifier()))
             connectionInfo = getWebAuthnProcessConnection(*parentProcessConnection());
 
-        if (!IPC::Connection::identifierIsValid(connectionInfo.identifier()))
+        if (!IPC::Connection::identifierIsValid(connectionInfo.identifier())) {
+            RELEASE_LOG_ERROR(WebAuthn, "ensureWebAuthnProcessConnection: Connection identifier for WebAuthn process is invalid.");
             CRASH();
+        }
 
         m_webAuthnProcessConnection = WebAuthnProcessConnection::create(connectionInfo.releaseIdentifier());
     }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to