macOS IPC between two Applications and Security

Hi,

I have a macOS application say Main.app which uses Helper App say Helper.app with UI support. Helper.app is placed inside Main.app/Contents/Library/LoginItems/Helper.app.
Helper.app is launched using NSWorkSpace and when user opts to launch Helper.app on login, SMLoginItemSetEnabled is turned ON for Helper.app.
Main.app and Helper.app communicate with each other via NSConnection. 
Helper app supports set of features based on some Condition and same condition is used to validate a feature in Main.app. Hence, Main.app talks to Helper.app to check if a feature can be validated.
1) Can someone write their version of Helper.app with same bundle identifier as my Helper.app and expose a connection with same name (when my Main.app and Helper.app is not running).
2) Now when Main.app is launched, it get connected to 3rd party Helper.app.

There are two versions of Main.app
  • > Main.app and Helper.app both are sandboxed and Belong to same group.

  • > Main.app and Helper.app both are not sandboxed (But, hardened run time is enabled). Groups are not defined.

Thank you.

Regards,
Deepa

Main.app and Helper.app communicate with each other via NSConnection.

Whoah there! What are you doing with NSConnection? That’s part of Distributed Objects (DO) and has been deprecated for some years now. And it wasn’t deprecated by accident. It has serious technical problems, both in terms of reliability and security.

Do not use Distributed Objects for new code. If you have existing code that uses DO, you should already have a plan to move it to something that’s actively supported.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Yes, NSConnection has been deprecated quite long back and due to some constraints we could not migrate. I would like to know if NSXPCConnection will be the right approach for communication between Main and Helper app. We need to share some data too between Main and Helper app.

If NSXPCConnection is the right approach in the following context

  1. Can someone write their version of Helper.app with same bundle identifier as my Helper.app and expose a xpc-connection with same service name (when my Main.app and Helper.app is not running).
  2. Now when Main.app is launched, it get connected to 3rd party Helper.app.

I would like to know if NSXPCConnection will be the right approach for communication between Main and Helper app.

Probably. It depends on the specific details. Let’s start with an easy one: Are you targeting the Mac App Store? Or independent distribution using Developer ID signing?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I am targeting both.

OK.

With regards your core issue, preventing impersonation, my general advice is that you lean in to XPC. XPC has facilities to check the identity of the connection’s remote peer, so you could have the helper app check the identity of the main app and vice versa. Once you do that it doesn’t matter if someone manages to usurp your XPC service name because neither app will talk to the usurper.

Actually doing this with XPC has traditionally been tricky but there’s been some very useful developments in this space recently. See this thread for more on that.

Coming back to your original post, you wrote:

Helper.app is launched using NSWorkSpace and when user opts to launch Helper.app on login, SMLoginItemSetEnabled is turned ON for Helper.app.

The best way to solve this problem is with an Service Management login item. This can publish an XPC service which is visible to the app, as demonstrated by the AppSandboxLoginItemXPCDemo sample code.

However, this only works if you launch it via SMLoginItemSetEnabled. If you launch it via NSWorkSpace it’s launches as a normal app and thus the system doesn’t publish its XPC service. How you handle that kinda depends on your app’s UI. If you can tweak the app’s UI so that the main app requires that the user enable the help login item, you’re all set. If not, things get trickier.

One option in that case is to move the core code out of the helper app into a framework that you share between the main app and the helper. If the user hasn’t enabled the login item, you call this core code directly rather than indirectly via the helper. You can modify this core code to store all of its state in an App Group, so that it’s available if the user decides to enable the login item.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I was thinking of using App Groups for common user data. Thank you very much for the response.

What if we have old code which uses NSConnection

It’s probably best to put the details of this issue into a new thread. Tag it with Inter-process communication so that I see it.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

macOS IPC between two Applications and Security
 
 
Q