How to avoid my local server flows in Transparent App Proxy

I have written the Transparent App Proxy and can capture the network flow and send it to my local server. I want to avoid any processing on the traffic outgoing from my server and establish a connection with a remote server, but instead of connecting to the remote server, it again gets captured and sent back to my local server.

I am not getting any clue on how to ignore these flows originating from my server.

Any pointers, API, or mechanisms that will help me?

Answered by DTS Engineer in 835370022

Your transparent proxy provider has methods like handleNewFlow(_:) where it decides whether it wants to handle the flow or not. Those methods are given the flow, that is, an object of type NEAppProxyFlow [1]. That object has a metaData property, with information about the origin of the flow. This has a few properties for identifying that origin. The right one to use is platform specific [2]. On the Mac you want sourceAppAuditToken, which you can feed into the code signing machinery to identify the main executable of the process in which the flow originated.

That last step is something I’ve discussed a bunch of times here on the forums, for example, here. That post has a warning about how to securely identify code. Heed it! To learn more about designated requirements, see TN3127 Inside Code Signing: Requirements.

Share and Enjoy

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

[1] Which is actually one its subclasses.

[2] While transparent proxies are only supported on the Mac, NEAppProxyFlow is also used by app proxies, which are supported on other platforms.

Accepted Answer

Your transparent proxy provider has methods like handleNewFlow(_:) where it decides whether it wants to handle the flow or not. Those methods are given the flow, that is, an object of type NEAppProxyFlow [1]. That object has a metaData property, with information about the origin of the flow. This has a few properties for identifying that origin. The right one to use is platform specific [2]. On the Mac you want sourceAppAuditToken, which you can feed into the code signing machinery to identify the main executable of the process in which the flow originated.

That last step is something I’ve discussed a bunch of times here on the forums, for example, here. That post has a warning about how to securely identify code. Heed it! To learn more about designated requirements, see TN3127 Inside Code Signing: Requirements.

Share and Enjoy

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

[1] Which is actually one its subclasses.

[2] While transparent proxies are only supported on the Mac, NEAppProxyFlow is also used by app proxies, which are supported on other platforms.

Thank you for your prompt response and the clarification. I’ve reviewed your code, which appears to be quite effective in identifying the source application. However, I’m encountering an issue where retrieving the bundle ID for certain flows results in an error code 100001. Interestingly, the code works as expected for system applications.

Could you please advise on the correct approach to reliably obtain the PID and bundle ID for any app flow? I’d appreciate it if you could let me know if I’ve misunderstood or missed something in the implementation.

func bundleIDForAuditToken(_ tokenData: Data) -> String? {
// Get a code reference.
var codeQ: SecCode? = nil
var err = SecCodeCopyGuestWithAttributes(nil, [
kSecGuestAttributeAudit: tokenData
] as NSDictionary, [], &codeQ)
guard err == errSecSuccess else {
return nil
}
let code = codeQ!
// Convert that to a static code.
var staticCodeQ: SecStaticCode? = nil
err = SecCodeCopyStaticCode(code, [], &staticCodeQ)
guard err == errSecSuccess else {
return nil
}
let staticCode = staticCodeQ!
// Get code signing information about that.
var infoQ: CFDictionary? = nil
err = SecCodeCopySigningInformation(staticCode, [], &infoQ)
guard err == errSecSuccess else {
return nil
}
let info = infoQ! as! [String:Any]
// Extract the bundle ID from that.
guard
let plist = info[kSecCodeInfoPList as String] as? [String:Any],
let bundleID = plist[kCFBundleIdentifierKey as String] as? String
else {
return nil
}
return bundleID
}
Written by dhanraj_kawade in 835796022
retrieving the bundle ID for certain flows results in an error code 100001.

Right. Error 100001 is the Security framework version of EPERM:

% security error 100001
Error: 0x000186A1 100001 UNIX[Operation not permitted]

It’s likely that the App Sandbox or MAC is blocking your access to the relevant app. See On File System Permissions.

If it’s the App Sandbox, you can get around this limit using a temporary exception entitlement. See App Sandbox Resources.

Share and Enjoy

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

How to avoid my local server flows in Transparent App Proxy
 
 
Q