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

Post

Replies

Boosts

Views

Activity

Ship fat framework with Privacy manifest file containing required reason API also with code signing
Hi I have built framework that I distribute to other organization and they use it in their App. Since I ship the Fat framework (.framework) and not the .xcframework, does Fat framework(from Xcode 15) containing privacy manifest file will be supported? Or do I have to convert the fat framework to the xcframework in order to use privacy manifest file and also code signing? Thanks in the advance.
4
0
582
Oct ’23
How to identify whether a passkey is created from an Apple device (iCloud Keychain)
Hi, I am currently implementing the ability to allow users to add a Passkey to their account by using the webuathn api. My current issue is that I would like to identify what type of device/authenticator the user has used to create their passkey so that we can automatically set a nickname for the passkey for the user to help the user experience (E.g. if a user has setup a passkey on an Apple device, we would auto set the nickname as iCloud Keychain so its clear to the user that the passkey is not specific to just the device they set it up on). After some reading, it seems like when trying to create a new passkey via an Apple device, it will not send a populated attestation with any sort of attestation statement, aaguid, fmt etc... and this is what I have been seeing in my testing of my implementation. My question is, instead of using an aaguid, is there an alternative way to identify that the user has created a passkey via iCloud Keychain? I can see that when creating a passkey to my Google account via my iPhone/Macbook, they seem to be able to identify when a passkey is created on an Apple Device and labels it automatically as ("iCloud Keychain") and this applies to both doing it via platform and cross-platform. I essentially want to be able to achieve this but I'm not sure how this can be done.
2
0
1.3k
Oct ’23
Endpoint Security event muting issue
Recently we've discovered an issue affecting our products in regards to using the Monterey+ provided new api calls to selectively mute events. Specifically, whenever using es_mute_process_events or es_mute_path_events, the ES_EVENT_TYPE_NOTIFY_OPEN event is ignored for muting (meaning the call will return success, but the event will keep coming). This is true only for this event as far as I can tell, its AUTH counterpart stays muted (along lots of other processes: clone, rename, close, unlink, fork etc). It fails if either the event is in a list of events or if the event is singled out in 1 sized vector of events. When using a dedicated client for this event and using the previous api, es_mute_process or es_mute_path muting works as intended. Tested on ventura 13.5 and 13.6. Is there something that can be done to prevent dedicated clients or is this a known issue?
5
0
870
Oct ’23
Lock Screen does not invoke Authorization Plugin as expected on macOS 14.0
I'm the developer of a Mac app that uses an authorization plugin to perform 2FA (password and approve in mobile app). There are four authorization use cases which we handle by updating the corresponding entries in the authorization database. The plugin is installed in the authorization database as follows: system.login.console -> login Replace: loginwindow:login With: TrusonaAuthorizationPlugin:trusonaLogin authenticate -> privilege escalation Replace: builtin:authenticate With: TrusonaAuthorizationPlugin:trusonaLogin system.login.screensaver -> lock screen Replace: use-login-window-ui With: authenticate-session-owner-or-admin system.login.fus -> fast user switching Replace: loginwindow:login With: TrusonaAuthorizationPlugin:trusonaLogin Im macOS Sonoma 14.0 attempting to unlock the screen invokes the Privilege Escalation mechanism regardless of whether the "system.login.screensaver" record in the authorization database points to our authorization plugin or not. When our authorization plugin is enabled for Lock Screen, clicking on the Lock Screen item in the Apple Menu invokes our authorization plugin for 2FA saying you need to authenticate to unlock the screen even though the desktop is not hidden. Filed as FB13238136
0
0
430
Oct ’23
EC signature verification failed (ccerr -7)
Hello, I am working on simple task, i have a JWT and I need to verify it's signature. My sample data: JWT eyJhbGciOiJFUzI1NiIsImtpZCI6IjhEWVpUTFRPVUtNSjdUU0w4SFZVVTlUVEdXMV9NTVVSSURJV1JUVE0iLCJ0eXAiOiJKV1QifQ.eyJub25jZSI6Indkd2R3ZHdkIiwiZGF0ZVRpbWUiOiIyMDIzLTEwLTEzVDEyOjQ4OjQwWiJ9.nWBfRne9VOKV4NGt32gWtoA5fUKzu0RzkhUYSYwUA7cvalsABUcWrpEk0fhztPZDK7KrDF8P2Pquhoxq4p-FUg Public key (JWK) { "kid": "8DYZTLTOUKMJ7TSL8HVUU9TTGW1_MMURIDIWRTTM", "use": "sig", "kty": "EC", "alg": "ES256", "crv": "P-256", "x": "8dyzTlToUkMJ7tsl8HVuU9tTGw1_mmuridIWrttMRCs", "y": "AVqGlqJ88QgP_uVLea7gIUnA-p9iYwnJyYt7o-uH4oU" } When you put the data to the [https://jwt.io] you get "Signature Verified" message. So the data should be ok. I have implementation in Objective-C, but i get this weird error message when the SecKeyVerifySignature is called. Here is my code: #import <Cocoa/Cocoa.h> #import <CommonCrypto/CommonDigest.h> NSString* base64StringWithPadding(NSString *encodedString) { NSString* stringTobeEncoded = [[encodedString stringByReplacingOccurrencesOfString:@"-" withString:@"+"] stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; int paddingCount = encodedString.length % 4; for (int i = 0; i < paddingCount; i++) { stringTobeEncoded = [stringTobeEncoded stringByAppendingString:@"="]; } return stringTobeEncoded; } SecKeyRef restorePublicKey(NSString *x, NSString *y) { NSString *xBase64Padd = base64StringWithPadding(x); NSString *yBase64Padd = base64StringWithPadding(y); NSData *xData = [[NSData alloc] initWithBase64EncodedString:xBase64Padd options:kNilOptions]; //32bytes NSData *yData = [[NSData alloc] initWithBase64EncodedString:yBase64Padd options:kNilOptions]; //32bytes NSMutableData *publicKeyData = [NSMutableData data]; // Append the constant byte '04' to indicate uncompressed format const unsigned char uncompressedByte = 0x04; [publicKeyData appendBytes:&uncompressedByte length:1]; // Append the X-coordinate and Y-coordinate [publicKeyData appendData:xData]; [publicKeyData appendData:yData]; NSDictionary *keyAttributes = @{ (id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPublic, (id)kSecAttrKeySizeInBits: @256, (id)kSecAttrIsPermanent:@NO }; CFErrorRef error = NULL; SecKeyRef publicKeyRef = SecKeyCreateWithData( (__bridge CFDataRef)publicKeyData, (__bridge CFDictionaryRef)keyAttributes, &error ); if(!publicKeyRef) { NSError *err = CFBridgingRelease(error); NSLog(@"%@", err.description); } return publicKeyRef; } int main(int argc, const char * argv[]) { @autoreleasepool { NSDictionary *jwk = @{ @"kid": @"8DYZTLTOUKMJ7TSL8HVUU9TTGW1_MMURIDIWRTTM", @"use": @"sig", @"kty": @"EC", @"alg": @"ES256", @"crv": @"P-256", @"x": @"8dyzTlToUkMJ7tsl8HVuU9tTGw1_mmuridIWrttMRCs", @"y": @"AVqGlqJ88QgP_uVLea7gIUnA-p9iYwnJyYt7o-uH4oU" }; SecKeyRef publicKeyRef = restorePublicKey(jwk[@"x"], jwk[@"y"]); NSString* header = @"eyJhbGciOiJFUzI1NiIsImtpZCI6IjhEWVpUTFRPVUtNSjdUU0w4SFZVVTlUVEdXMV9NTVVSSURJV1JUVE0iLCJ0eXAiOiJKV1QifQ"; NSString* payload = @"eyJub25jZSI6Indkd2R3ZHdkIiwiZGF0ZVRpbWUiOiIyMDIzLTEwLTEzVDEyOjQ4OjQwWiJ9"; NSString* signature = @"nWBfRne9VOKV4NGt32gWtoA5fUKzu0RzkhUYSYwUA7cvalsABUcWrpEk0fhztPZDK7KrDF8P2Pquhoxq4p-FUg"; NSString *headerAndPayload = [NSString stringWithFormat:@"%@.%@", header, payload]; NSData *signedData = [headerAndPayload dataUsingEncoding:NSUTF8StringEncoding]; NSString *signatureBase64Padd = base64StringWithPadding(signature); NSData *signatureData = [[NSData alloc] initWithBase64EncodedString:signatureBase64Padd options:kNilOptions]; bool canVerify = SecKeyIsAlgorithmSupported(publicKeyRef, kSecKeyOperationTypeVerify, kSecKeyAlgorithmECDSASignatureMessageX962SHA256); if(canVerify) { CFErrorRef error = NULL; BOOL verifyStatus = SecKeyVerifySignature( publicKeyRef, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (__bridge CFDataRef)signedData, (__bridge CFDataRef)signatureData, &error ); if(error) { NSError *err = CFBridgingRelease(error); NSLog(@"%@", err.description); } } else { NSLog(@"Cannot verify."); } } return NSApplicationMain(argc, argv); } I dont know where is the problem. I've tried everything.
2
0
450
Oct ’23
DeviceActivityReportExtension working on IOS 17 device but not on IOS 16 device
When I run it on my IOS 16 device I get this error message. When I run it on my device with IOS 17 I get none of these logs. My build target for both the widget and app are 16.0. "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=66, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} 2023-10-19 13:49:44.565845-0400 Halo[87980:7963095] [db] Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=66, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} 2023-10-19 13:49:44.569345-0400 Halo[87980:7963095] Metal API Validation Enabled
2
1
662
Oct ’23
codesign not signing helper executable in AppleScript bundle
My AppleScript .app bundle contains a helper executable. Table 3 of TN2206 says that executables may be in either Contents/MacOS or Contents/Helpers, but Quinn's first reply in this post says that Contents/MacOS is better. So I put the helper in Contents/MacOS, alongside applet. I sign the AppleScript .app bundle for Developer ID and Hardened Runtime by running the codesign command with arguments recommended by Quinn in this post. Result: Notary Service rejects the .app bundle due to 3 issues with the helper: is not signed with a valid Developer ID certificate does not include a secure timestamp does not have the hardened runtime enabled (Possibly it still has a years-old signature without Developer ID and Hardened Runtime). So it seems that the the helper is not being (re-)signed. If, instead of signing the .app bundle, I run Quinn's codesign comand twice, once on the applet and once on the second executable, then Notary Service is happy with the bundle. I was hoping that, after all these years, codesign is now smart enough to find and sign all of the executables inside a bundle. Both executables are x86_64 non-fat (I guess I should fatten those) and I have installed Xcode 15.1 Beta. Should I file a bug, or am I doing something wrong?
1
0
554
Oct ’23
Are financial/banking aggregators not allowed in the App Store?
Hi! After over a year published in the App Store and with all 5-star ratings, my free, ad-free and open source app has been rejected this week during a routine bugfix update (literally a 1-line change in the code). The reviewer claims my app breaks this rule: (ix) Apps that provide services in highly regulated fields (such as banking and financial services, healthcare, gambling, legal cannabis use, and air travel) or that require sensitive user information should be submitted by a legal entity that provides the services, and not by an individual developer. Apps that facilitate the legal sale of cannabis must be geo-restricted to the corresponding legal jurisdiction. All my app does is use an open, public and free API offered by an investment firm in my country that allows their customers to access their account data programatically. This allows them to integrate things like their account balance or history in spreadsheets, websites, widgets, etc. For instance, people are already using Scriptable to create homescreen widgets that show their live balance in the homescreen. You just log in to the official firm's website, generate a personal token, and then input that token in whichever app/spreadsheet you want in order to make the corresponding HTTP requests. Now, my app does NOT collect any data whatsoever. When you open it, the app fetches your account data from these GET (read-only) endpoints and shows it to you with a nice presentation, including pleasant interactive charts that users really like. But the data only lives in memory, and as soon as you exit the app, it's all gone. No account creation, no data collection, no data storage, nothing. Zero. It's like sending a Postman request, but having the response plotted in nice charts for you. That's all. The ONLY thing that can (optionally) be stored locally in your device is your access token, so you don't have to copy and paste it every time you open the app. And it is securely encrypted in your iPhone and protected biometrically. That's it. The reviewer claims that, because my app presents sensitive financial information to the user, it must be published directly through the official company account of the investment firm, not by me. But isn't that what hundreds of popular banking/brokerage aggregators do? They just use read-only, open APIs to consolidate all your positions across banks/broker accounts, then present it to you in a single place. I understand these apps are not breaking any rules, right? So how is my app different? Am I missing something? To add to this, the investment firm is well aware of the existence of my app, and they not only approve of it, but are highly supportive and have encouraged me to continue improving it, as it shows the kind of things that are possible with their API. They've repeatedly helped me solve technical doubts whenever I've had any issues. So this is really a win-win for everyone and there's zero conflicts here. Do you think the reviewer is right? Or is he misinterpreting the policy? My impression is that the policy is aimed at apps that COLLECT sensitive data, not those who just PRESENT it to the user. But even though I've tried to explain this to him, he won't budge. What options do I have? Just to be clear, my app doesn't offer "financial services" of any kind on top of this. It simply shows you the same information you can see in the raw JSON that the API returns, or in the official app/website, but in a nicer format. It's clean, aseptic, unadulterated data, without any commercial business behind it. No offering or soliciting of any other products, just a pure and clean presentation of the data. Any advice would be greatly appreciated, as I'd like to get a second opinion before sending a FOURTH reply to the reviewer. I'd hate having to make my app an Android exclusive because of a simple policy misinterpretation :(
4
0
719
Oct ’23
Not using "Required Reason API", but actually receiving same output through invoking system call
stat() is in the "Required Reason API" list. https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api I do not use stat() in my app, but I use assembler instruction to invoke stat system call. And for a security purpose, I use its return value to check existence of some files and directories outside the app container. I use system call instead of API for a security reason. Q. Do I have to declare that my app uses "Required Reason API"?
3
0
488
Oct ’23
Bypass ASLR for debugging purposes
Hello, Look at this basic C program: #include <stdio.h> int main() { printf("%llx\n", main); return 0; } The displayed address change on each run. This is due to ASLR. Is there a way to launch a program by forcing the main module's base address I would like to do something like that in my terminal: $ BASE_ADDRESS=0x10000 ./a.out How can i do that on mac os ? Is it possible to force base address loading for shared libraries too ? Thanks
3
0
843
Oct ’23
The ASCredentialProviderViewController method is not executing.
Hello, when I attempted to use the passkey, the method - (void)prepareCredentialListForServiceIdentifiers:(NSArray<ASCredentialServiceIdentifier *> *)serviceIdentifiers requestParameters:(ASPasskeyCredentialRequestParameters *)requestParameters API_AVAILABLE(ios(17.0), macos(14.0)) API_UNAVAILABLE(watchos, tvos); didn't execute. Are there any specific prerequisites for this method to run? I would appreciate your assistance. Thank you.
3
0
501
Oct ’23
Developer account required for key generation
I've been reading information/signing data using keys in the file keychain without too many problems but the other day I tried to generate a private key in the file and the secure enclave keychains and I faced the -30418 error. I made sure that the entitlements were correct based on previous posts but still no luck. Code kind of based off this: https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/protecting_keys_with_the_secure_enclave Do you actually need to pay for the $99/per year developer account to generate private keys inside the keychains ?
1
0
750
Oct ’23
SecKeyCreateSignature with LAContext.invalidate
I have some code where I'm using SecKeyCreateSignature using a SecKey that I retrieved using SecCopyItemMatching with an LAContext provided to the query via the kSecUseAuthenticationContext parameter. This is a biometrically-backed key so a Touch ID prompt is displayed for the user. Calling LAContext.invalidate() while that system prompt is present doesn't dismiss the prompt or cancel the SecKeyCreateSignature call. I was hoping that would behave similar to how calling LAContext.invalidate when calling LAContext.evaluatePolicy and dismiss the system prompt and cancel the evaluatePolicy call. Is this a bug/oversight, expected behaviour, or am I missing some required setup to accomplish what I'm trying to do?
1
0
730
Oct ’23
How to prolong showing custom UI in Lockscreen of MacOS.
Hello, I made a mechanism that shows my custom user interface in the lock screen of MacOS by using the example in https://developer.apple.com/library/archive/samplecode/NameAndPassword/ The UI is being displayed as required and working perfectly. But it will automatically gets removed form display when there is no input from user for 30 seconds. I need to prolong that time as I need to support multiple factor verifications such as push notification(where user need to accept push notification in mobile device rather than in mac), security key(where user needs to insert and tap a security device without needing to give any input in keyboard or trackpad). Please suggest me any solution regarding the ways to achieve this. Any information is appreciated. Thank you.
1
0
521
Oct ’23
App does not show camera usage description
My app was rejected because the camera usage description was too vague. When I went back to update it with clearer language, the description now does not show up at all. I've edited the Privacy - Camera Usage Description in info.plist targeting the iOS app but it still does not show up. I looked at this old thread but I've already followed the steps suggested therein to no avail.
2
0
568
Oct ’23
App Name missing from Touch ID Request on macOS
Hi there, bit of an odd one, we have no idea how this happened but now we can't seem to figure out how to fix. Our app requests Touch ID on macOS to authenticate a user. This is done in the ever so standard way [LAContent evaluatePolicy:...]... Functionally everything is fine, but for some reason there is no App Name on the system dialog... We don't even know when this started happening... Our App Icon is there but not the name, it's blank so the dialog looks strange (see attached pic). The text doesn't really make sense without the App Name. I wouldn't have even thought this was possible, the standard info.plist keys like CFBundleName and CFBundleDisplayName are all set correctly. Everything else seems totally fine. We're seeing this across every target/build/version/sku so it seems unrelated to a particular plist. There are no localizations for the App Name either, no InfoPlist.strings involved here. What could cause this, does anyone know? @eskimo, I'm afraid turning things up to 11 didn't help, so hoping you've got an idea?
6
0
865
Oct ’23
algorithm kSecKeyAlgorithmRSASignatureRaw not support on mac platform when using the method SecKeyCreateSignature
On my mac platform I try to use the method SecKeyCreateSignature to sign data with algorithm kSecKeyAlgorithmRSASignatureRaw but always failed. I double checked the support status but it failed with sample code: if (!SecKeyIsAlgorithmSupported(privKeyRef, kSecKeyOperationTypeSign, kSecKeyAlgorithmRSASignatureRaw)) {return 0;} But on my iOS client, the kSecKeyAlgorithmRSASignatureRaw works well. If I can not use the algorithm kSecKeyAlgorithmRSASignatureRaw, which algorithm I can use to get the same signed result by sign the given to-be-signed raw data.
1
0
399
Nov ’23