What is the Hardened Runtime?¶
macOS 10.14 and Xcode 10 introduce a new feature called 'Hardened Runtime'. It is intended to enhance the security of applications by disabling/disallowing various kinds of loading third-party executable code into the AUT - such as Squish libraries.
It effectively disables various features commonly exploited in security breaches.
The information in this article are only applies to automating applications which are configured to use the Hardened Runtime with Squish.
Hardened Runtime Entitlements required by Squish¶
Squish for Qt and Squish for Mac are both affected by the Hardened Runtime, because both use the same mechanism for non-intrusive hooking.
Entitlement Allow DYLD Environment Variables
¶
Allow DYLD Environment Variables is always required to be able to inject code into the running AUT process (which is what Squish is doing).
Entitlement Disable Library Validation
¶
Disable Library Validation is need to avoid that every library, which Squish attempts to load into the AUT process, needs to be signed. (Required because the Squish libraries loaded into the AUT process are not signed with the digital certificate of the AUT developer.)
While disabling library validation is certainly easier, there may be reasons not to do this. With Squish for Qt it also works to use the built-in hook and code-signing all Squish libraries that are being loaded into the AUT (with the digital certificate of the AUT developer).
(The steps required to make Squish's quickaddressbook example work with library validation enabled are explained further down on this page.)
Entitlement Allow Execution of JIT-compiled Code
¶
Allow Execution of JIT-compiled Code
is required on ARM (Apple Silicon) based CPUs if the AUT uses
JavaScriptCore
. (For example if it uses
WebKit
/
WKWebView
for embedding web views.)
Without this entitlement (or if it is disabled), the AUT will likely crash when the web view of the application initializes "JavaScriptCore" (specifically in JSC::SecureARM64EHashPins::initializeAtStartup()
).
Checking for Hardened Runtime¶
It may be an option to simply ask the application developer.
Besides that, the tool codesign
(provided separately by Apple) can be used to check. It is part of Xcode, but also of the Xcode Command Line Tools. The easiest way to install it is by executing one of the following commands in Terminal - this should prompt installation of the Xcode Command Line Tools:
clang
gcc
git
( source )
Once installed, execute this command:
This command produces an output that looks something like this:
The flags
entry indicates which flags have been enabled. If the runtime
flag (0x10000) is present, the application uses the hardened runtime feature. If it is not set - like in the example output above - the application does not use the hardened runtime.
Checking for existing Entitlements¶
The Hardened Runtime supports exceptions to individual items, called 'entitlements', which comprise the Hardened Runtime.
And some of these entitlements are required for automation through Squish.
To find out which entitlements are already enabled in for an executable:
This produces output in the form of a plist file that looks like this:
In this output, check if these keys exist and are set to true:
Key | Capability | Entitlement |
---|---|---|
com.apple.security.cs.disable-library-validation | Hardened Runtime | Disable Library Validation |
com.apple.security.cs.allow-dyld-environment-variables | Hardened Runtime | Allow DYLD Environment Variables |
If they're missing, or set to false, hooking with Squish will fail.
If the application is sandboxed, additional measures need to be taken into account.
Adding Hardened Runtime Entitlements¶
In an Xcode Project¶
After making such changes, the application typically needs to be rebuilt.
(Also see Hardened Runtime .)
For an existing executable using codesign
(manually)¶
It is possible to sign an executable manually via the codesign
command line tool. This requires an Apple developer certificate.
(codesign
is provided via Xcode and/or the Xcode Command Line Tools. Installation of the "Xcode Command Line Tools" can be triggered by executing one of the following commands in a shell/Terminal (
source
): clang
, gcc
, git
.)
The general syntax is:
codesign --entitlements /path/to/entitlements.plist -s <identity> /path/to/executable
<identity>
refers to your code-signing identity. To list of available code-signing identities on the local computer:
security find-identity -v -p codesigning
entitlements.plist
must be a text file in 'plist' format, for example (obtained by executing: codesign -d --entitlements - --xml /System/Applications/TextEdit.app | xmllint --format -
):
Testing with Library Validation Enabled¶
(Optional) Preparing Squish's quickaddressbook example for Hardened Runtime testing¶
This is not strictly necessary, however it will give you a minimal project to compare your own setup to. All commands given here are prepared to be executed inside the build directory where qmake was run. IDENTITY
refers to your code-signing identity. This prints a list of available identities:
security find-identity -v -p codesigning
- Configure the project to use Xcode projects for building so that entitlements can be added easily:
qmake -spec macx-xcode ../quickaddressbook
- Open the generated Xcode project, add the "hardened runtime" capability and check "Allow DYLD Environment Variables"
- Build the app through Xcode (Cmd-B)
- Run
macdeployqt
on the newly built app bundle to add required Qt libraries:macdeployqt Debug/quickaddressbook.app -codesign=IDENTITY -hardened-runtime -timestamp -qmldir=path/to/quickaddressbook/qml
- Unfortunately,
macdeployqt
overwrites our custom entitlements. Re-sign with correct entitlements:codesign -fs IDENTITY --deep --timestamp -o runtime --entitlements quickaddressbook.entitlements Debug/quickaddressbook.app
Signing Squish for Qt libraries¶
This script signs all necessary libraries of Squish for Qt 7.0.
#!/bin/sh
set -eu
if [[ "$#" -ne 2 ]]; then
echo "Usage: ${0} signing_identity squish_prefix"
exit 1
fi
export IDENTITY="${1}"
export SQUISH_PREFIX="${2}"
export ORIGINAL_PWD=$PWD
cd "${SQUISH_PREFIX}"
codesign -fs "${IDENTITY}" --deep --timestamp -o runtime lib/libsquishhook.dylib
codesign -fs "${IDENTITY}" --deep --timestamp -o runtime lib/libtracelib.dylib
codesign -fs "${IDENTITY}" --deep --timestamp -o runtime lib/libsquishqt*
codesign -fs "${IDENTITY}" --deep --timestamp -o runtime lib/extensions/qt/libsquishqt*
# Squish >= 7.0
codesign -fs "${IDENTITY}" --deep --timestamp -o runtime lib/libav*
codesign -fs "${IDENTITY}" --deep --timestamp -o runtime lib/libswscaleSquish.5.dylib
cd ${ORIGINAL_PWD}
It is used like this:
./sign-squish-qt.sh IDENTITY "/path/to/Squish for Qt 7.0.0"
Related Information¶
Information from Apple about using the codesign
tool: