Post

Replies

Boosts

Views

Activity

How to register a login item with SMAppService?
In macOS 13 there's now the SMAppService object which can be retrieved for a login item via its loginItem(identifier:) function. However, the documentation for this function doesn't make sense, it reads in part: The property list name must correspond to a property list in the calling app’s Contents/Library/LoginItems directory This function doesn't take a property list name, it takes a (presumably bundle) identifier. Is it safe to assume despite the documentation that the officially designed behavior is actually the same as the now deprecated SMLoginItemSetEnabled(_:_:) function and that actually there must be a bundle in the calling app'sContents/Library/LoginItems directory with that bundle identifier? I know I can try this out myself and see what happens, but I've found with Apple it's never a good idea to make assumptions which don't match documented behavior.
0
1
609
Jun ’22
Swift package for parsing & evaluating code requirements
I thought some folks on this forum might find it useful, so I'm sharing that I've just open sourced a Swift package called Required which parses and evaluates requirements written in Apple's Code Signing Requirement Language. Amongst other uses, this package can be quite useful in debugging security requirements used to secure XPC communications. This package only uses public APIs and supports OS X 10.10 and later. (The parser itself has no platform dependencies at all and could in theory be run on any platform Swift supports.) As an example of how the package works, to see whether and how an application satisfies its designated requirement: // Retrieve the designated requirement for Numbers let url = URL(fileURLWithPath: "/Applications/Numbers.app") var code: SecStaticCode? SecStaticCodeCreateWithPath(url as CFURL, [], &code) var requirement: SecRequirement? SecCodeCopyDesignatedRequirement(code!, [], &requirement) // See whether and how Numbers satisifies its designated requirement let abstractRequirement = try Parser.parse(requirement: requirement!) let evaluation = try abstractRequirement.evaluateForStaticCode(code!) print("Does \(url.lastPathComponent) satisfy its designated requirement?") print(evaluation.isSatisfied ? "Yes" : "No") print("\nEvaluation tree:") print(evaluation.prettyDescription) Which outputs: Does Numbers.app satisfy its designated requirement? Yes Evaluation tree: and {true} |--() {true} | \--or {true} | |--and {true} | | |--anchor apple generic {true} | | \--certificate leaf[field.1.2.840.113635.100.6.1.9] {true} | \--and {false} | |--and {false} | | |--and {false} | | | |--anchor apple generic {true} | | | \--certificate 1[field.1.2.840.113635.100.6.2.6] {false}¹ | | \--certificate leaf[field.1.2.840.113635.100.6.1.13] {false}² | \--certificate leaf[subject.OU] = K36BKF7T3D {false}³ \--identifier "com.apple.iWork.Numbers" {true} Constraints not satisfied: 1. The certificate <Apple Worldwide Developer Relations Certification Authority> does not contain OID 1.2.840.113635.100.6.2.6 2. The certificate <Apple Mac OS Application Signing> does not contain OID 1.2.840.113635.100.6.1.13 3. The certificate <Apple Mac OS Application Signing> does not contain element subject.OU
1
0
871
Jun ’22
Validating an XPC connection in a sandboxed process
I'm working on a macOS app that I'd like to sandbox along with a login item that I'd also like to sandbox. Login items implicitly have an XPC Mach service created for them which my app is able to successfully use communicate with the sandboxed login item (because they're in the same application group). The issue is that any non-sandboxed process can also connect to my login item's XPC Mach service, and I'd really rather that wasn't the case. I realize there's no privilege escalation going on, but this feels unnecessarily insecure. My attempts to secure the connection keep failing due to sandboxing. Is there a way to do what I'm attempting or is Apple's intention that any non-sandboxed process on the system ought to be able to successfully communicate with my login item? If I don't sandbox my login item it's trivial for me to secure this connection. Here's what I've tried so far: Path based Retrieve the SecCode using SecCodeCreateWithXPCMessage Retrieve the SecStaticCode using SecCodeCopyStaticCode Retrieve the path of the static code using SecCodeCopyPath Compare this path with my login item's path based on Bundle.main.bundleURL This fails on step 2, the SecCodeCopyStaticCode function gets back a "UNIX error exception: 1". This kind of makes sense to me as it needs to read from the file system in order to get the static code of the running process. Code requirements based Retrieve the SecCode using SecCodeCreateWithXPCMessage Construct a SecRequirement including amongst other things that certificate leaf[subject.OU] = <my team id> Use SecCodeCheckValidity on the code instance from step #1 and the requirement from step #2 This fails on step 3, SecCodeCheckValidity also results in a "UNIX error exception: 1". Looking at the logs generated by sandboxd it looks like under the hood that function calls _CFBundleGetBundleVersionForURL and fails. The violation is: deny(1) file-read-data ~/Library/Developer/Xcode/DerivedData/LoginItemSample-ajfwjiwmyuphdbeyugmssxszdlyq/Build/Products/Debug/LoginItemSample.app Is there perhaps some combination of SecCSFlags values I can pass to prevent any file system access?
6
0
1.6k
Apr ’22