Allow "Browser" to find devices on local networks

Hi, I am developing the browser based on Chromium, which initially relies on the nw_browser stack for discovering locally available network resources.

We have observed an issue where, after each software update—specifically, whenever additional files are written into the application bundle—a popup appears requesting the user to allow local network access, even if this permission was already granted.

The behavior is reproducible: simply overwriting files in the app bundle (we are using rsync as Chromium), even while the application is already running, causes the prompt to reappear. We have also noticed that Chromium itself exhibits the same behavior.

Also I found the mess in system settings, it has several Google Chrome for example: https://www.loom.com/share/da401f39ab134628807d77f1ca3185f5?from_recorder=1&focus_title=1

We would like to provide a smoother experience for our users and avoid confusing them with repeated permission prompts.

Could you please advise on possible approaches or best practices to improve our update mechanism in this regard?

Answered by DTS Engineer in 858749022

I’d like to clarify your overall goal here. Are you planning to ship an app based on Chromium? Or are you building some sort of plug-in that you install within Chromium?

This matters because…

simply overwriting files in the app bundle

Right. That breaks the seal on the code signature, which causes problems for all privacy subsystems, which rely on the code signature to track the identity of your code, that is, to determine that version N+1 of your app is the ‘same code’ as version N. This is something we call out in TN3179 Understanding local network privacy:

To ensure that local network privacy reliably tracks the identity of your macOS program, sign it with an Apple-issued code-signing identity.

Most apps don’t suffer from this problem because, when Xcode rebuilds the app, it signs result. If you’ve selected an Apple-issued code-signing identity, the new app has the same designated requirement as the previous app, and thus the OS treats it as the same app, and so the new version inherits all the privileges acquired by the old version. We talk about this more in TN3127 Inside Code Signing: Requirements.

If you’re modifying the contents of your app bundle but not re-signing it, you will encounter weird problems.

Share and Enjoy

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

I’d like to clarify your overall goal here. Are you planning to ship an app based on Chromium? Or are you building some sort of plug-in that you install within Chromium?

This matters because…

simply overwriting files in the app bundle

Right. That breaks the seal on the code signature, which causes problems for all privacy subsystems, which rely on the code signature to track the identity of your code, that is, to determine that version N+1 of your app is the ‘same code’ as version N. This is something we call out in TN3179 Understanding local network privacy:

To ensure that local network privacy reliably tracks the identity of your macOS program, sign it with an Apple-issued code-signing identity.

Most apps don’t suffer from this problem because, when Xcode rebuilds the app, it signs result. If you’ve selected an Apple-issued code-signing identity, the new app has the same designated requirement as the previous app, and thus the OS treats it as the same app, and so the new version inherits all the privileges acquired by the old version. We talk about this more in TN3127 Inside Code Signing: Requirements.

If you’re modifying the contents of your app bundle but not re-signing it, you will encounter weird problems.

Share and Enjoy

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

Hi Quinn,

Thank you for your reply!

After your advice I checked the code signing, and here’s what I found:

With every release of our software, we sign all binaries using the codesign utility, and each binary has static Designated Requirements that don’t change from release to release. Overall, our signing process is the same as everyone else’s, and as far as I know, the original Chromium faces the same update issues https://issues.chromium.org/issues/346505950.

Moreover, Chromium developers made opinion in (https://issues.chromium.org/issues/346505950#comment31) that

this local network permission is associated with the specific Mach-O UUIDs of an application rather than being tied to a code signing identity like most other TCC permissions are on macOS. The network extension subsystem listens for LaunchServices notifications about an application being installed and updates the Mach-O UUIDs it associates with an application's bundle identifier. This means that when LaunchService sees a new version of an application, the local network permission is lost for prior versions of that application, even if they're still running.

In our case, with every Rsync update, a new Contents/Frameworks/Comet Framework.framework/Versions/A.B.C.D folder with the updated version is added, and the main binary changes.

However, the Designated Requirements remain the same. Here’s an example of how I checked (note the version numbers: 140.0.7339.20465 and 139.0.7258.18212)

find "/Applications/Comet.app" -type f -print0 | xargs -0 file | grep -E 'Mach-O' | awk -F: '!/\(for architecture/ {print $1}' | sort -u | xargs -I {} codesign --display -r - "{}"

https://gist.github.com/poluyanov/78893d8d574694164d7c5d310a1dcafa

It seems that the problem might lie elsewhere, and I may be missing something.

I really appreciate your help with this, Quinn.

Best. IP

Ah, yes, Chrom{e,ium}. There’s definitely something weird going on there, but I’ve yet to see a definitive answer as to what it is. It certainly isn’t as simple as ‘local network using build UUIDs for everything’, because if that were the case then all apps would lose their local network privacy privilege after every update. However, it’s also true that the network subsystem uses build UUIDs in ways that I’m not super happy with.

a new …/Versions/A.B.C.D folder with the updated version is added

Wha? You’re relying on framework versions? That is… well… not what I’d do. That’s not been best practice for a long time, and our docs are now clear about that.

Is the local network call being made by the process running your app’s main executable? Or by, perhaps, a helper tool embedded in this framework?

Is this issue causing grief for your users? Or only during development?

After reproducing the problem, what does this print:

% codesign -d -vvv "/Applications/Comet.app"

And this:

% codesign -v -vvv --deep --strict "/Applications/Comet.app"

Share and Enjoy

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

You’re relying on framework versions?

Actually, no — that’s just how Chromium organizes its build.

Is the local network call being made by the process running your app’s main executable? Or by, perhaps, a helper tool embedded in this framework?

Chromium does network request out of Main process, in helper process in framework.

/Applications/Comet Dev.app/Contents/Frameworks/Comet Dev Framework.framework/Versions/140.0.7339.20748/Helpers/Comet Dev Helper.app/Contents/MacOS/Comet Dev Helper --type=utility

Here I prepared two videos with demos: Usually it is easy reproducible when open Google meet…

Here I run a regular build with local network permissions, mount the new build, run rsync, and catch the issue: https://www.loom.com/share/0e1dcafdf6c645e9a34087e36414bc78

As an experiment, I also prepared two builds with a static UUID for each Mach-0 generated by my patched LLD (UUID based on hash of the filename): https://www.loom.com/share/d48b6365a4154a3ba8da8f921ad445ca

In this case I cannot reproduce the issue — I tried many times. I could be wrong, You will probably see more on your side.

Both repros show the same output for the commands you requested:

% codesign -v -vvv --deep --strict "/Applications/Comet Dev.app"

and

codesign -d -vvv "/Applications/Comet Dev.app"

Is this issue causing grief for your users?

Yes, unfortunately, many users are complaining about this pop-up that still appears even when permissions have already been granted.

Thank you for participating

Allow "Browser" to find devices on local networks
 
 
Q