Prioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.

All subtopics

Post

Replies

Boosts

Views

Activity

Can the Endpoint Security Extension communicate with a regular app
I'm developing a system that uses an ES extension to control user file openings on Mac. When a user tries to open a file, the ES extension can either allow or deny the user from opening it. However, the policy for allowing/denying users to open files is managed by my normal Mac app. Therefore, the ES extension needs to proactively communicate with the normal app. Initially, I wanted to create an XPC service in my regular app, but according to the documentation, XPC services are managed by launchd and cannot be created by regular apps. So if I want my ES extension to communicate with the regular app proactively, what IPC method can I use?
1
0
40
8h
SWIFT: server certificate does NOT include an ID which matches the server name
I'm working on MBP OSX Ventura 13.5.2 I'm working with Swift 5 (Xcode 15.2) I have a local httpd configured with vhosts. I create my local certs using mkcert. When I visit the https://example site with Chrome the certificate is perfectly valid and there are no issues. When I try and contact the same site using a DataCallBack function to the URL I get the error "server certificate does NOT include an ID which matches the server name" In the log: Connection 1: default TLS Trust evaluation failed(-9807) Connection 1: TLS Trust encountered error 3:-9807 Connection 1: encountered error(3:-9807)
2
0
64
18h
In macOS, is it possible to have a hardware-bound key in the system context?
We are interested in using a hardware-bound key to sign requests made to a server prior to a user being logged in. We would do this using a launch daemon. The goal here is to have a high degree of assurance that a request came from a particular device. The normal way to do this would be with a private key in the Secure Enclave. Based on these threads: https://forums.developer.apple.com/forums/thread/719342 https://forums.developer.apple.com/forums/thread/115833 and the write-up about the Data Protection Keychain, it doesn't appear possible with the SE. Rather, it seems that we must wait until we have a logged-in user context before we can use the SE. My questions are: am I correct in that the SE is not usable in the system context prior to login? is there any other way on macOS to sign a request in such a way that we know it comes from a specific device? Thanks.
2
0
63
20h
Custom Authorization Plugin for macOS: Issue with MCXSecurityAgent.invoke Error
Hi everyone, I'm currently developing a custom authorization plugin for macOS and have encountered an issue that I need help with. I've modified the auth DB to use my custom plugin instead of the default login window. Although I'm able to set both the name and password as context values, the login process is failing, and I'm seeing the following error in the security agent log: <string>builtin:prelogin</string>     <string>builtin:policy-banner</string>     <string>MyPlugin:login</string>     <string>MyPlugin:value</string>     <string>builtin:login-begin</string>     <string>builtin:reset-password,privileged</string>     <string>loginwindow:FDESupport,privileged</string>     <string>builtin:forward-login,privileged</string>     <string>builtin:auto-login,privileged</string>     <string>builtin:authenticate,privileged</string>     <string>PKINITMechanism:auth,privileged</string>     <string>builtin:login-success</string>     <string>loginwindow:success</string>     <string>HomeDirMechanism:login,privileged</string>     <string>HomeDirMechanism:status</string>     <string>MCXMechanism:login</string>     <string>CryptoTokenKit:login</string>     <string>PSSOAuthPlugin:login-auth</string>     <string>loginwindow:done</string> I am setting name and password in MyPlugin:login and also able to see same in MyPlugin:value mechanics. 2 2024-07-25 06:53:30.813047-0700 0x2e3b Info 0x0 822 0 SecurityAgentHelper-x86_64: (MyPlugin) *****The name and password is test and test1234**** But 2024-07-25 02:33:00.777530-0700 0x8772 Debug 0x0 1527 0 SecurityAgent: (MCXMechanism) [com.apple.ManagedClient:MCXSecurityPlugin] MCXSecurityAgent.invoke kAuthorizationEnvironmentName is NULL 2024-07-25 02:33:00.777530-0700 0x8772 Debug 0x0 1527 0 SecurityAgent: (MCXMechanism) [com.apple.ManagedClient:MCXSecurityPlugin] MCXSecurityAgent.invoke - user logging in is '(null)' Has anyone encountered this issue before or have any insights into what might be causing the kAuthorizationEnvironmentName is NULL error and why the user logging in is shown as '(null)'? Any guidance or suggestions on how to resolve this would be greatly appreciated.
2
0
68
1d
Screen recording TCC permission overcome?
Hi, I am developing a background screen recording app and macOS Sequoia is constantly blocking the app after restart with a nag screen "Confirm to continue the screen recording". That's looking insane! I know that the built-in Grab Screenshot app is not requesting any permission and that is an anti-competitive beaviour! I have found inside the compiled code the following plist XML code that disables the software firewall TCC, implemented by Apple. It's undocumented for no reason. Anyone knows how to repeat this unblocking tweak?
2
0
63
1d
macOS Sequoia beta 3: SecPKCS12Import failed with error - 23000
In our App, we store identity in keychain in a specific path var keychain: SecKeychain? let status = SecKeychainCreate(path, UInt32(password.count), password, false, nil, &keychain) guard status == errSecSuccess else { logger.error("Error in creating keychain: \(String(describing: SecCopyErrorMessageString(status, nil)))") throw KeychainError.keychainCreationError } Then later whenever process needs it. it open keychain, import it and uses it. status = SecPKCS12Import(identityData as CFData, [kSecImportExportPassphrase : password, kSecImportExportKeychain: keychain] as CFDictionary, &identityItems) authlog.info("Import status: \(status)") guard status == errSecSuccess else { authlog.error("Error in exporting identity : \(status) \(String(describing:SecCopyErrorMessageString(status, nil)))") throw ClientAuthError.identityFormationError } This worked well till sequoia beta 2. In Sequoia beta 3 and 4, this fails to import with error -25300 : The specified item could not be found in the keychain. one thing I noticed is import succeeds if the keychain is freshly created. when tried to reuse existing keychain it fails in import error. Is this a bug in beta or it any changes made in keychain level by Apple itself. Please help with the solution Log trace: [ 24-07-2024 12:39:15:192 ] [INFO] Challenge delegate received [ 24-07-2024 12:39:15:192 ] [INFO] Client authentication challenge [ 2024-07-24 12:39:15 ] [INFO] retcode of "/bin/chmod -R 777 "/Library/<path>/data/agent-resource"" ::: 0 [ 24-07-2024 12:39:15:237 ] [INFO] Opening keychain... [ 24-07-2024 12:39:15:240 ] [NOTICE] Keychain open status: -25294 [ 24-07-2024 12:39:15:241 ] [ERROR] Keychain error: Optional(The specified keychain could not be found.) [ 24-07-2024 12:39:15:241 ] [INFO] Creating keychain.. [ 24-07-2024 12:39:15:448 ] [INFO] Import status: 0 [ 24-07-2024 12:39:15:448 ] [INFO] Identity: <SecIdentity 0x7ff3ec1f7df0 [0x7ff85540e9a0]> [ 24-07-2024 12:39:15:448 ] [INFO] Credential sent [ 24-07-2024 12:39:15:581 ] [INFO] Upload request completed.. [ 24-07-2024 12:39:15:583 ] [INFO] Status code: 200 [ 25-07-2024 12:24:55:300 ] [INFO] Client authentication challenge [ 25-07-2024 12:24:55:300 ] [INFO] Opening keychain... [ 25-07-2024 12:24:55:305 ] [NOTICE] Keychain open status: 0 [ 25-07-2024 12:24:55:439 ] [INFO] Import status: -25300 [ 25-07-2024 12:24:55:440 ] [ERROR] Error in exporting identity : -25300 Optional(The specified item could not be found in the keychain.) [ 25-07-2024 12:24:55:440 ] [CRITICAL] Error in getting identity: identityFormationError [ 25-07-2024 12:24:55:441 ] [ERROR] Error in obtaining identity [ 25-07-2024 12:24:55:513 ] [INFO] Download request complete... [ 25-07-2024 12:24:55:515 ] [INFO] Status code: 200
1
0
53
1d
How to forbid SharePlay on IOS 18 ?
Hello, I saw that, in IOS 18 + FaceTime + SharePlay, we can take the control of another device (for support an user for example). I would like to block the use of SharePlay on my application. My application does not include Capabilites "Group Activities", but I do not know whether this is sufficient to block the use of SharePlay. What do you think ? Thanks in advance for your returns.
0
0
87
2d
macOS Sandbox and writing to system folders (audio plug-Ins)
Hello macOS gurus, I am writing an AUv3 plug-in and wanted to add support for additional formats such as CLAP and VST3. These plug-ins must reside in an appropriate folder /Library/Audio/Plug-Ins/ or ~/Library/Audio/Plug-Ins/. The typical way these are delivered is with old school installers. I have been experimenting with delivering theses formats in a sandboxed app. I was using the com.apple.security.temporary-exception.files.absolute-path.read-write entitlement to place a symlink in the system folder that points to my CLAP and VST3 plug-ins in the bundle. Everything was working very nicely until I realize that on my Mac I had changed the permissions on these folders from to The problem is that when the folder has the original system permissions, my attempt to place the symlink fails, even with the temporary exception entitlement. Here's the code I'm using with systemPath = "/Library/Audio/Plug-Ins/VST3/" static func symlinkToBundle(fileName: String, fileExt: String, from systemPath: String) throws { guard let bundlePath = Bundle.main.resourcePath?.appending("/\(fileName).\(fileExt)") else { print("File not in bundle") } let fileManager = FileManager.default do { try fileManager.createSymbolicLink(atPath: systemPath, withDestinationPath: bundlePath) } catch { print(error.localizedDescription) } } So the question is ... Is there a way to reliably place this symlink in /Library/... from a sandboxed app using the temporary exception entitlements? I understand there will probably be issues with App Review but for now I am just trying to explore my options. Thanks.
2
0
125
2d
ASWebAuthenticationSession does not work for some reason for an OAuth Authorization Code grant
Hi there, I'm having some trouble with getting a OAuth Authorization Code redirect with a custom scheme to work with ASWebAuthenticationSession. I am trying to build an app that integrates with an authentication provider, in which I have configured like this: Callback URL: myapp://auth In my iOS app, I have define this as a custom scheme in my info.plist file. <dict> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLName</key> <string>com.abc.def</string> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> </dict> <dict/> </array> </dict> Excuse the messy-ish code below, but I just want to see this work. import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { AContentView() .onOpenURL { url in print("Received URL in onOpenURL: \(url)") Self.handleURL(url) } } } static func handleURL(_ url: URL) { print("Handled URL: \(url)") } } import AuthenticationServices struct AContentView: View { @Bindable var viewModel = SomeViewModel() @State private var authSession: ASWebAuthenticationSession? @State private var presentationContextProvider = PresentationContextProvider() var body: some View { VStack { Button(action: doIt) { Text("Authenticate") } } } func doIt() { Task { @MainActor in await viewModel.onLaunchAsync() // this asynchronously gets some stuff that is used to build `viewModel.loginUrl` authenticate() } } func authenticate() { let authURL = viewModel.loginUrl! // Replace with your auth URL let callbackURLScheme = "myapp" authSession = ASWebAuthenticationSession(url: authURL, callback: .customScheme(callbackURLScheme)) { callbackURL, error in if let error = error { print("Authentication error: \(error.localizedDescription)") return } guard let callbackURL = callbackURL else { print("No callback URL") return } print("Callback URL: \(callbackURL)") MyApp.handleURL(callbackURL) } authSession?.presentationContextProvider = presentationContextProvider authSession?.start() } } class PresentationContextProvider: NSObject, ASWebAuthenticationPresentationContextProviding { func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { return UIApplication.shared.windows.first! } } I'm running Proxyman, and can see the calls the iOS app makes. When I click the "authenticate" button, I get the expected request to open Safari, and login to a web form provided by an authentication provider. Next, I am redirected to a "choose consents" page, where I can choose scopes. Finally, on this page, I click "Allow" at the bottom of this list of scopes, but instead of being 'sent' back to the app, the redirect doesn't work. The final API call the web screen makes is to a /consent endpoint which replies with an HTTP 302, and a Location header as below: Location: myapp://auth#code=<something>. This doesn't close the window, either in a simulator or a real device. I can verify that my scheme is working correctly, as if I manually in Safari browse to myapp://auth#code=1234 it asks me if I want to open in my app, and I can see my print firing off. Am I missing something? What am I doing wrong here? While I could implement this myself using WKWebView / WKNavigationDelegate to intercept the new location, see if its my custom scheme, and then close it out, that seems hacky, and AFAIK ASWebAuthenticationSession should support my use-case. Many thanks!
1
0
119
2d
Secure Enclave with symmetric keys
Hi Folks, I have a need to create and store a 256 bit symmetric key that I use to encrypt and decrypt data stored on disk. There is also a need to continue to do this both in the backgroud and in the application extensions. As far as I know, SE does not work with symmetric key, but there is an option to encrypt the symmetric key with an SE-protected asymmetric key. The question arises, how is this different from just storing the key in Keychain, since I can't take advantage of SE's main advantage of not storing the key in memory, even for a short time. (Anyway, I can't not store the key in memory anyway, because the key is used by a third-party framework.) Should I also use SE for this purpose, decrypt my symmetric key, give the symmetric key to the framework for a short time and then zeroize it?
2
0
93
2d
How can I grant full disk access to a Node-RED instance?
I just updated to Sonoma on a Mac Mini that runs all my ad-hoc DIY home automations, and I have a bunch of custom self-made tools for triggering automations based in part on the state of reminders in the Reminders app. All of that stopped working immediately after the update. It took me a day to update my code for the new location of the sqlite reminders files and I made the changes to get my scripts working again, however one remaining problem is that I run an fswatch from node-red to monitor the database for changes to trigger my automations. Eventually, with help from stack and perlmonks, I found out that even though the permissions on the full path (via my home directory/Library) to the files is r*x to me and the node-red executable is running as me, I get an Operation not permitted error when I just try lsing the directories leading to the sqlite files. I read elsewhere that this sort of problem can be solved by granting full disk access to the executables(/processes) that are getting the Operation not permitted errors. However, I tried this, yet I still get the same error. Do I need to reboot? Is there some sort of documentation for casual users like myself that just code for themselves that can answer questions like this? The more aggressive Apple gets with security, the safer users are, but the more headaches and bewilderment it causes people like me.
6
0
115
2d
SecureEnclave.PrivateKey properties
Hi, Is there some reference documentation about the properties of a CryptoKit SecureEnclave PrivateKey and its properties? Concretely, these are some of the questions that I wanted to find a (documented) answer on: Who can use a SecureEnclave.P256.*.PrivateKey if they have access to the dataRepresentation? I expect that the private key is bound to the specific secure enclave processor, but it also seems to be bound for the user that created the key (from observation by creating a PrivateKey without any access control). What if there's a restore from backup of the machine, will the private key still be usable? What does a SecureEnclave.P256.*.PrivateKey's dataRepresentation include? From observation, I'm assuming the dataRepresentation is a signed/encrypted blob that includes a unique ID (no 2 keys are the same), the access control settings (biometry required, passcode required, ...), some sort of version of the biometry (so it is be invalidated when the biometry changes). Is there anything else? I'm not interested in the actual encoding (which I understand is undocumented), but want to get an idea of what properties are included in the representation and e.g. can't change in the future. Answers to these questions could e.g. help make a decision how secure the private key's dataRepresentation needs to be kept (e.g. if it can only be used by myself, and i'm sure it will only ever be valid with the access control flags its representation contains, I could decide it's ok to have this key be in a public place) I tried looking for answers in some pieces of documentation, but couldn't immediately find the details I was looking for: The CryptoKit SecureEnclave documentation The Secure Enclave article The Protecting keys with the Secure Enclave article thanks! Remko
0
0
76
2d
App content protection failure
I have set kCGWindowSharingState to none for my app. Even though the sharing state is none, I am still able to record my app's content using the native screen recording app and third-party apps. My App window detaills: { kCGWindowAlpha = 1; kCGWindowBounds = { Height = 700; Width = 1000; X = 1956; Y = 105; }; kCGWindowIsOnscreen = 1; kCGWindowLayer = 0; kCGWindowMemoryUsage = 2176; kCGWindowName = "Create and Sell Online Training Programs - TrainerCentral"; kCGWindowNumber = 13352; kCGWindowOwnerName = TrainerCentral; kCGWindowOwnerPID = 95409; kCGWindowSharingState = 0; kCGWindowStoreType = 1; }
3
0
95
3d
Smart Card Command Fails on macOS 14
I'm encountering an issue related to PCSC (PC/SC) smart card interactions on macOS 14 that I haven't experienced on earlier versions of macOS. When sending an APDU command to generate a key pair on a smart card: On macOS 12: The operation works as expected. On macOS 14: The card responds with an error 66 02. Are there any any changes to PCSC implementation in macOS 14 that might affect smart card operations?
1
0
69
3d
Question about advertising
Hello, I made a game (RPG) and I would like to add an option to unlock custom sprite/skin for characters. This option is not essential to use the app. That is the system that I want to make for this unlock option : A link in the app send the player on a website. The custom sprite could be unlocked by looking around 20 pages on a website (with contains advertising). At the pages number 20, a code is displayed and the player can use it in the app. (Page 1 send to page 2, page 2 to page 3... until page 20) Is it allowed? An other question about advertising for children. I read the guidelines, some rules are specific for children. Some data couldn't be collected. What is the age exact for those rules please? Thank you
0
0
96
3d
Sign in With Apple Problem on iOS
I am implementing Sign In With Apple for a web app, and am having trouble with signing in on an iOS device. I manually create the Auth URL, of the format: https://appleid.apple.com/auth/authorize?response_type=code&state={STATE}&client_id={MY_CLIENT_ID}&redirect_uri={MY_REDIRECT_URI}&scope=openid+name+email&response_mode=form_post When a user clicks the Sign In link on desktop, it brings me to the screen shown below. After entering your Apple ID and password, a login event with a code is sent to my backend/Redirect URI. Everything works as expected and the user is logged in successfully. On iOS (I've tested in both Chrome and Safari for iPhone), clicking the link gives me the following popup. Hitting continue appears to complete the login process, but nothing happens. No code is sent to my Redirect URI, and the user is not logged in. It seems like Apple is just "swallowing" this login and not sending the appropriate request to my Redirect URI. What is happening? How can I fix this?
0
0
73
4d
iOS DeviceCheck API call returning 400 all the time
Hi, I'm getting 400 Missing or badly formatted authorization token everytime I call the following API from my local Server ( I tried calling this API from my app itself as well) curl --location 'https://api.development.devicecheck.apple.com/v1/query_two_bits' \ --header 'Authorization: Bearer <<JWT-token>>' \ --header 'Content-Type: application/json' \ --data '{ "device_token": Token_fetched_from_Device_Check, "transaction_id":"c6bdb659-0ee6-443d-88cb-a8f036dfc551", "timestamp": 1721300244267 }' "device_token" - I have generated from DeviceCheck framework JWT-token - I generated using key from .p8 file generated from Apple developer portal, keyId of the same and the team Id ( I have individual account) IMP Points- I have created this .p8 file from apple developer account, and I did enable Device check option while creating the key. I also tried calling this API after 7 hours ( and more then that as well) of creating key from the developer portal as I have read somewhere that the key gets activated after few hours. I understand (again read somewhere) that the token created by DeviceCheck framework has some expiration time so I tried with freshly created token several times as well. This is how I'm generating token using DeviceCheck - if curDevice.isSupported{ DCDevice.current.generateToken { (data, error) in if let data = data { } } } JWT token generation - func createJWTToken(privateKey: String, keyID: String, teamID: String) -> String? { // Set up the JWT header var jwtHeader = Header() jwtHeader.kid = keyID // Set up the JWT claims let jwtClaims = MyClaims(iss: teamID, iat: Date()) // Create the JWT var jwt = JWT(header: jwtHeader, claims: jwtClaims) // Convert the private key to Data guard let privateKeyData = Data(base64Encoded: privateKey) else { print("Invalid private key") return nil } // Sign the JWT let jwtSigner = JWTSigner.es256(privateKey: privateKeyData) do { let signedJWT = try jwt.sign(using: jwtSigner) return signedJWT } catch { print("Failed to sign JWT: \(error)") return nil } } But no luck, please suggest something. any sort of help is much appreciated. Thank you
1
0
105
4d