我的应用是否被沙盒化?如何检测?

19

我有一个应用程序,旨在在沙盒和非沙盒的MacOS上运行。 如果用户从MacOS 10.6升级到更高版本的操作系统,则需要用户重新选择文件夹,以便我可以使用安全书签来标记它们。

如何检测我的应用程序是否在支持沙盒的操作系统上运行?

5个回答

25

我知道的唯一方法是查找APP_SANDBOX_CONTAINER_ID环境变量。只有当应用程序在沙盒容器内运行时,它才存在。

NSDictionary* environ = [[NSProcessInfo processInfo] environment];
BOOL inSandbox = (nil != [environ objectForKey:@"APP_SANDBOX_CONTAINER_ID"]);

正是我在寻找的!我会尝试一下,如果有效我会修改这个评论。谢谢。 - NPAssoc
注意:这在macOS Sierra(beta 1、2和3)上不再起作用。 - Kyle

8
BOOL isSandboxed = NO;

SecStaticCodeRef staticCode = NULL;
NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];

if (SecStaticCodeCreateWithPath((__bridge CFURLRef)bundleURL, kSecCSDefaultFlags, &staticCode) == errSecSuccess) {
    if (SecStaticCodeCheckValidityWithErrors(staticCode, kSecCSBasicValidateOnly, NULL, NULL) == errSecSuccess) {
        SecRequirementRef sandboxRequirement;
        if (SecRequirementCreateWithString(CFSTR("entitlement[\"com.apple.security.app-sandbox\"] exists"), kSecCSDefaultFlags,
                                       &sandboxRequirement) == errSecSuccess)
        {
            OSStatus codeCheckResult = SecStaticCodeCheckValidityWithErrors(staticCode, kSecCSBasicValidateOnly, sandboxRequirement, NULL);
            if (codeCheckResult == errSecSuccess) {
                isSandboxed = YES;
            }
        }
    }
    CFRelease(staticCode);
}

1
它检查指定应用程序包是否存在有效的“com.apple.security.app-sandbox”授权。如果是“是”,则表示应用程序已被沙盒化。 您可以在此处找到详细的API信息:https://developer.apple.com/reference/security - Oleksii

5

测试Swift3

func isSandboxed() -> Bool {
    let bundleURL = Bundle.main.bundleURL
    var staticCode:SecStaticCode?
    var isSandboxed:Bool = false
    let kSecCSDefaultFlags:SecCSFlags = SecCSFlags(rawValue: SecCSFlags.RawValue(0))

    if SecStaticCodeCreateWithPath(bundleURL as CFURL, kSecCSDefaultFlags, &staticCode) == errSecSuccess {
        if SecStaticCodeCheckValidityWithErrors(staticCode!, SecCSFlags(rawValue: kSecCSBasicValidateOnly), nil, nil) == errSecSuccess {
            let appSandbox = "entitlement[\"com.apple.security.app-sandbox\"] exists"
            var sandboxRequirement:SecRequirement?

            if SecRequirementCreateWithString(appSandbox as CFString, kSecCSDefaultFlags, &sandboxRequirement) == errSecSuccess {
                let codeCheckResult:OSStatus  = SecStaticCodeCheckValidityWithErrors(staticCode!, SecCSFlags(rawValue: kSecCSBasicValidateOnly), sandboxRequirement, nil)
                if (codeCheckResult == errSecSuccess) {
                    isSandboxed = true
                }
            }
        }
    }
    return isSandboxed
}

2

以下是 Swift 4.2 中 @hamstergene 的答案:

func isSandboxEnvironment() -> Bool {
    let environ = ProcessInfo.processInfo.environment
    return (nil != environ["APP_SANDBOX_CONTAINER_ID"])
}

ProcessInfo.processInfo.environment["APP_SANDBOX_CONTAINER_ID"] != nil - undefined
已确认在 macOS 10.15.7 上工作正常。 - undefined

0
我翻译了@Oleksii的代码的新Swift 5版本。
import Security

extension Bundle {
    var isSandboxed: Bool {
        let defaultFlags: SecCSFlags = .init(rawValue: 0)
        var staticCode: SecStaticCode? = nil
        
        if SecStaticCodeCreateWithPath(self.bundleURL as CFURL, defaultFlags, &staticCode) == errSecSuccess {
            if SecStaticCodeCheckValidityWithErrors(staticCode!, SecCSFlags(rawValue: kSecCSBasicValidateOnly), nil, nil) == errSecSuccess {
                let requirementText = "entitlement[\"com.apple.security.app-sandbox\"] exists" as CFString
                var sandboxRequirement: SecRequirement?
                if SecRequirementCreateWithString(requirementText, defaultFlags, &sandboxRequirement) == errSecSuccess {
                    if SecStaticCodeCheckValidityWithErrors(staticCode!, defaultFlags, sandboxRequirement, nil) == errSecSuccess {
                        return true
                    }
                }
            }
        }
        return false
    }
}

使用方法:

isSandboxed = Bundle.main.isSandboxed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接