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

Keychain private key signing error
When performing biometric authentication, some times we are getting these kind of errors when i try to sign the data with private key that we get it from keychain. I was searching for document related to this but i could not.Can someone help me on this? Error message and error code Remote alert invalidated -4 UI canceled by system -4 unable to sign digest -3 Canceled by another authentication -4 Caller is not running foreground -1004 Caller moved to background -4 No identities are enrolled  -7 User has denied the use of biometry for this app -1018 Application retry limit exceeded -1 Face ID interlocked -8 Biometry lost -4 match failed -1 // To get signed data using private key SecKeyRef privateKeyReferences = [self getPrivateKey:keyNames]; if(!privateKeyReferences) { NSLog(@"Error retrieving private key"); return nil; } NSError *error; NSData *signature = CFBridgingRelease(SecKeyCreateSignature(privateKeyReferences, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef) data, (void *)&error)); if(!signature) { NSString *errorMessage = [NSString stringWithFormat:@"Error signing data %@.", error]; NSLog(@"%@", errorMessage); return nil; } return signature;
2
0
454
Feb ’24
Even when calling the Apple Login Revoke API, the app still remains in the user's account.
Problem Situation User membership withdrawal request → revoke API call It always returns status code 200, but once out of 5~10, it remains an app linked to the user's Apple ID. Re-request user Apple login → Email is returned as null Currently, the only solution is for users to manually delete apps linked to their Apple ID. Email sent when re-requesting Apple login When the above problem occurs, even if the Revoke API is called multiple times, the app linked to the user's Apple ID is not deleted, and when requesting Refresh Token validation, it has already expired. Releated Issues https://forums.developer.apple.com/forums/thread/707181
1
0
691
Feb ’24
Can't grant the permission in Flutter.
Hi, I encounter a problem about the permission using Flutter. I already add the following items in iOS/Runner/Info.plist <key>NSCameraUsageDescription</key> <string>We need access to your camera to take photos.</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>We need to access your current location for manage the dispatching routing.</string> <key>NSLocationWhenInUseUsageDescription</key> <string>We need to access your current location for manage the dispatching routing.</string> <key>NSMicrophoneUsageDescription</key> <string>We need access your microphone to talk to driver.</string> <key>NSPhotoLibraryUsageDescription</key> <string>For uploading driver's report including dispatch and clock in/out</string> And call this in my code: Map<Permission, PermissionStatus> statuses = await [ Permission.camera, Permission.locationWhenInUse, Permission.locationAlways, Permission.microphone, ].request(); But why there is no any dialog asking for permission and when going to settings-> "App name", and there are no items in "Allow {App Name} to Access" for setting permission manually. Can anyone help me? Thanks a lot. Here is the information of flutter doctor ``[✓] Flutter (Channel stable, 3.10.6, on macOS 13.6.4 22G513 darwin-x64, locale zh-Hant-TW) [✗] Android toolchain - develop for Android devices ✗ Unable to locate Android SDK. Install Android Studio from: https://developer.android.com/studio/index.html On first launch it will assist you in installing the Android SDK components. (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions). If the Android SDK has been installed to a custom location, please use `flutter config --android-sdk` to update to that location. [✓] Xcode - develop for iOS and macOS (Xcode 15.2) [✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable. [!] Android Studio (not installed) [✓] VS Code (version 1.62.0) [✓] VS Code (version 1.86.1) [✓] Connected device (2 available) [✓] Network resources``
1
1
746
Feb ’24
Bundle structure and its repercussions
I recently inherited a project to port an app bundle to arm64, and some of the design decisions in the app bundle are undocumented. I'd like to structure the bundle as canonically as possible, to minimize future problems as much as possible. In particular, there are two areas where I would like some clarification. I have read all of eskimo's guides (what a godsend!), but have not been able to find an explanation for these yet. We have some helper executables that allow us to run jobs in the background, etc... Historically, these have always been in Contents/Resources, for some reason; that seems to be a bad idea. I have seen conflicting advice suggesting to use Helpers or just MacOS. What are the advantages or disadvantages of using each folder? Would dumping all the executables in MacOS be an adequate solution and, if not, why should I use Helpers? Our app contains "compiled extensions" in Contents/SharedSupport, which consist of small intel-based apps (with their own app bundle) that our app can interact with. They are supposed to be a demo of extensions that the users could code and compile themselves, thus justifying their location. Should these be signed in any special way? Our app used to employ the --deep flag for code signing, but following eskimo's guidelines I have removed that, and it is not clear to me how these should be signed. Thank you.
1
0
506
Feb ’24
Why don't my Apps receive unconditional access to Keychain Items specified with -T parameter during creation?
Hi! I am trying to make a UI Testing target in Xcode for my Application (Client). It works with Keychain items that are created during installation, so in order to mock this installation behavior I am creating the items like this: security add-generic-password -U -D "[item_kind]" -a "[account]" -l "[label]" -s [service] -w "[value]" -T path/to/UITest-runner.app -T path/to/Client-app.app However, during UI Testing, the application is still prompted to access or modify the Keychain Items as seen in the bottom half of this screenshot: These application paths have been obtained by the find terminal command inside DerivedData/.../Build/Products/... so they are the correct paths (which is also proven I guess by the fact that the apps are correctly listed in the ACL window of Keychain Access as seen on the top half of the screenshot). I also tried using the -A option instead of -T but the result is exactly the same. Why doesn't this approach work during UI Testing? I am using the same approach in my installation script for the real application installation process with the -T parameters and there is no issue in that case. This issue kills my UI Tests because I am constantly prompted when I want to read of modify the contents of these Keychain Items.
2
0
567
Feb ’24
privacy manifest for static library framework
i have a code only static library framework and added PrivacyInfo.xcprivacy file inside. because there are no resources required in runtime, app using that framework can build without embedding. finally there are no PrivacyInfo.xcprivacy file in app bundle. is this correct intended operation? some steps to propagate and merge static framework's privacy manifest to app's privacy manifest not needed?
8
0
2.5k
Feb ’24
Apple Privacy Manifest - Instruments Debug Tracking Domain
Hi, I've implemented the Privacy Manifest in my app and specified my tracking domain as required, setting NSPrivacyTracking to true and listing my domain under NSPrivacyTrackingDomains However, on iOS17 when I decline the App Tracking Transparency (ATT) request, the specified tracking domain isn't blocked by iOS, contrary to my expectations. Shouldn't Apple's framework automatically block the domain and indicate this action in Instruments, allowing developers to verify the domain is indeed blocked when tracking is denied? <key>NSPrivacyTracking</key> <true/> <key>NSPrivacyTrackingDomains</key> <array> <string>traking.example.com</string> </array>
0
0
1.4k
Feb ’24
Privacy manifest files for SDKs
As the new requirement for Privacy manifests is coming this Spring 2024 (https://developer.apple.com/news/?id=r1henawx), Apple released a list of SDK's that need to comply with this requirement and provide a privacy manifest file: https://developer.apple.com/support/third-party-SDK-requirements/ I have a SDK project that does not fall under the mentioned requirements。 collects data uses of required reason API includes listed Third-party SDK I have some questions: Do I need to include a privacy manifest file in my SDK project? if so, is a blank privacy manifest file included in the SDK? if not, is it possible to publish an App that use my SDK, without a privacy manifest file?
0
1
758
Feb ’24
privacy manifests
Hello.We provide our customer with a SDK which we developed. Our customer demands us that our SDK supports privacy manifest requirement. We check if our SDK uses data,APIs and third party SDKs on the list Apple released. When our SDK don't use any data,APIs and third party SDKs, Should we add the privacy manifest file to our SDK?
2
1
922
Feb ’24
SFAuthorizationPluginView in the system.login.fus scenario.
Hello, Regarding authorization plugins, I am trying to display a user interface in the fast user switching (fus) scenario. I have implemented the SFAuthorizationPluginView class that theoretically would help me show a user interface in this context. doing tests, I see that my plugin window is displayed behind the fus background screen. This window in screen lock scenario is displayed correctly. Is there any limitation in fus that prevents displaying a UI above the background screen where the user enters the password? I show how I have system.login.fus configured(My plugin is MyTestPlugin): ... mechanisms <string>builtin:smartcard-sniffer,privileged</string> <string>loginwindow:login</string> <string>builtin:reset-password,privileged</string> <string>builtin:auto-login,privileged</string> <string>builtin:authenticate-nocred,privileged</string> <string>MyTestPlugin:invoke</string> <string>loginwindow:success</string> <string>loginwindow:done</string> I have tried placing my puglin in a different order compared to other mechanisms and it did not get the window to display above the background screen. Another option I've tried is to place my plugin on top of loginwindow:login. In this case, my plugin interface is displayed correctly but I do not have username information. Is there a way to obtain this information? All the best.
0
0
528
Feb ’24
Signature Creation with PrivateKey().signature(for:) vs SecKeyCreateSignature
Quick Summary I'm having trouble using SecKeyCreateSignature(deviceSigningKeyRef, .ecdsaSignatureMessageX962SHA256, digest, &amp;error) but when using SecureEnclave.P256.KeyAgreement.PrivateKey().signature(for: digest) the other code I'm using to verify succeeds. Full use case and code If I just initiate a SecureEnclave.P256.KeyAgreement.PrivateKey() class variable and then later use signature(for: digest).rawRepresentation to generate a signature, I get a signature value that can be passed to the verifying code class MyClass { var myPrivateKey: SecureEnclave.P256.KeyAgreement.PrivateKey? init() { myPrivateKey = SecureEnclave.P256.KeyAgreement.PrivateKey() let myPublicKey = myPrivateKey?.publicKey.rawRepresentation } func createAndSendSignature(_ digest: Data) { let signature = try? myPrivateKey?.signature(for: digest).rawRepresentation // 64 bytes sendSignatureWithDigest(signature, digest) } } But if I create my key in keychain via Secure Enclave with the way the documentation recommends (here's a few links to start Signing/Verifying, Keys for encryption), and then retrieve the key representation and use SecKeyCreateSignature, the resulting signature (which I manipulate a little more because it is DER encoded and does not comes back as 64 bytes) fails against the verifying code. class MyClass { var myKeyTag: String = "myKeyTag" func createAndStoreKey() { let access = SecAccessControlCreateWithFlags( kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .privateKeyUsage, nil)! // Ignore errors. let attributes: NSDictionary = [ kSecClass as String: kSecClassKey, kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits as String: 256, kSecAttrTokenID: kSecAttrTokenIDSecureEnclave, kSecPrivateKeyAttrs as String: [ kSecAttrIsPermanent as String: true, kSecAttrApplicationTag as String: myKeyTag, kSecAttrAccessControl as String: access, kSecAttrCanSign as String: true, ] ] var error: Unmanaged&lt;CFError&gt;? guard let keyRef: SecKey = SecKeyCreateRandomKey(attributes as CFDictionary, &amp;error) else { throw error!.takeRetainedValue() as Error } return keyRef as SecKey! } func getKey(){ let query: [String: Any] = [ kSecClass as String: kSecClassKey, kSecAttrApplicationTag as String: myKeyTag, kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecReturnRef as String: true, ] var item: CFTypeRef? let status = SecItemCopyMatching(query as CFDictionary, &amp;item) guard status == errSecSuccess else { throw KeyStoreError("Unable to retrieve key: \(status.message)") } return (item as! SecKey) } func createAndSendSignature(_ digest: Data) { let privKey = getKey() let signature = SecKeyCreateSignature( privKey, .ecdsaSignatureMessageX962SHA256, digest as CFData, &amp;error) as Data? else { print(error) return } // bytes varry due to DER encoding and R and S values let ecdsaSignature = try P256.Signing.ECDSASignature(derRepresentation: signature) let signatureBytes = ecdsaSignature.rawRepresentation sendSignatureWithDigest(signatureBytes, digest) } } An important note: digest is not an actual digest but a message that needs to be hashed to turn into a digest? Sorry if that sounds off, my security knowledge is limited. Please forgive any syntax errors, I can't copy and paste the code and am just extracting the important elements. Anything helps, thanks!
2
1
880
Feb ’24
The application is in inactive state after pressing the power button to lock the screen when using passkey
I am creating an app using flutter. When the application displays the passkey authentication dialog box, after the face id authentication is complete (the authentication dialog box has not yet closed), I press the power button to lock the screen. After that, when I unlock the screen, my application is still displayed but it is in inactive state. This means the interface is still visible but the user cannot interact.
1
0
421
Feb ’24
FIDO CTAP 2.2 hybrid transport state assisted transaction
In the context of a passkey authentication where a non apple desktop system relies on the ios device as an authenticator, je ios device requires the user to scan the qrcode of the desktop device every time an authentication on is required. in the same context, and Android device will allow the user to « remember » the established link to allow subsequent authentications to reuse the link without having to scan the qrcode each time. The android device behaviour is specified by FIDO at https://fidoalliance.org/specs/fido-v2.2-rd-20230321/fido-client-to-authenticator-protocol-v2.2-rd-20230321.html So my question is: when will ios support CTAP 2.2 hybrid transport state assisted transaction? The absence of it is a major obstacle to the general adoption of passkeys among ios users.
0
0
589
Feb ’24
Web Credentials aren't being recognized even though the AASA file is configured correctly
We have an App that displays a WKWebWiew. The page being loaded in the WebView loads a snippet with a button that when clicked, initiates WebAuthN Flow. The App throws he following [WebAuthn] Request cancelled after error: The operation couldn’t be completed. Application with identifier 123ABCDEF4.com.exmaple.app.staging is not associated with domain example.co.za. In the above quote, 123ABCDEF4 would represent the TeamID, com.exmaple.app.staging is the bundle identifier and example.co.za is the main/root domain while the WKWebView actually loads a URL at staging.example.co.za. in Xcode, the App's Associated Domains contains the following webcredentials:staging.example.co.za The AASA file hosted at https://staging.example.co.za/.well-known/apple-app-site-association returns the following { "applinks": { "details": [ { "appIDs": [ "123ABCDEF4.com.example.app", "123ABCDEF4.com.example.app.staging" ], "paths": [ "*" ] } ] }, "webcredentials": { "apps": [ "123ABCDEF4.com.example.app", "123ABCDEF4.com.example.app.staging" ] }, "appclips": { "apps": [] } } May you kindly advise what we may be doing wrong? The message being thrown refers to the fact that the Staging app is not associated with the root/main domain. If it's any consolation, we've updated both example.co.za and staging.exmaple.co.za to return the exact same AASA file where they both registers both Prod & Staging AppIds
2
0
1.2k
Feb ’24
Passkey Integration Question RE: iOS Generated authenticationData
I am integrating Apple's iOS implementation of WebAuthN using the ASAuthorization APIS provided by Apple. I am integrating with the Django py_webauthn host backend. I have the entire registration & account creations process working. And I almost have the account authentication process working. But there seems to be an issue between the version of authenticationData generated by iOS subsequent to the client (iPhone) authentication process and what py_webauthn is expecting. It results in a consistent "Leftover bytes detected while parsing authentication data" error on the host. According to the documentation, this error is generated when all the authenticatorData has been parsed but there are leftover bytes in the data. I believe if I get past this issue everything will be working. I could use some help here and provide code/logs below. But in the hopes that someone from the Authentication development team at Apple is watching for these posts, I have a related question. Can we assume that the generated private key AND sign_count data is shared across an iOS user's devices through KeyChain cloud? Do we have to advise our users that they should enable this?? Here is code (OBJ C) and logs, in the hopes that someone can advise... and hoping that the code can help others trying to implement this capability. Thanks..... iPhone Client - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization //Check to make sure that we are authenticating user after receiving authorization challenge from host NSLog(@"%s retrieve public/private key",__FUNCTION__); NSDictionary *pubKeyDict = [NSDictionary dictionary]; ASAuthorizationPlatformPublicKeyCredentialAssertion *appleCred = (ASAuthorizationPlatformPublicKeyCredentialAssertion *)authorization.credential; NSDictionary *clientJSON = [NSJSONSerialization JSONObjectWithData:appleCred.rawClientDataJSON options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%s clientJSON = %@",__FUNCTION__,clientJSON); NSString *clientJSONString = [ServerUtilities encodeBase64URLData:appleCred.rawClientDataJSON]; NSString *authenticatorString = [ServerUtilities encodeBase64URLData:appleCred.rawAuthenticatorData]; NSString *signatureString = [ServerUtilities encodeBase64URLData:appleCred.signature]; NSDictionary *respDict = [NSDictionary dictionaryWithObjectsAndKeys clientJSONString, @"clientDataJSON", authenticatorString, @"signature", signatureString, @"authenticatorData", nil]; NSLog(@"%s respDict - %@",__FUNCTION__,respDict); NSString *credIDString = [ServerUtilities encodeBase64URLData:appleCred.credentialID]; NSDictionary *regDict = [NSDictionary dictionaryWithObjectsAndKeys: credIDString, @"id", respDict, @"response", @"public-key",@"type", nil]; pubKeyDict = [NSDictionary dictionaryWithObjectsAndKeys: credentialEmail, kEMAIL, regDict, @"auth_cred", nil]; NSLog(@"%s pubKeyDict - %@",__FUNCTION__,pubKeyDict); //Post JSON serialized version of pubKeyDict to host Xcode log pubKeyDict - { "auth_cred" = { id = "JNMBbZF_PQM7O64RY_MXQqhAyKk"; response = { authenticatorData = "MEYCIQDgVFINihy9nPuuRrZWkLPahEfLy3huCV9_seOuM5gSlgIhAP_99EVQjXhyJy37ccRxQenSxt7oPNrQ4VjVDSW5Ej8l"; clientDataJSON = eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoidkhYcTdKTG05Z2dNU1BienNpZThFWUJsVW16V2N3WXlvOFBnT0FKMlR1b0VBbGVBbkQ0NGFNVDg3RG93YnZaZUNxLWxTdC1uNTFkUWJpVzgxNVhZRlEiLCJvcmlnaW4iOiJodHRwczovL2FuY2hvci1hd2F5LmNvbSJ9; signature = "WJ3tJNMYfNST99x-EAdNDrnsUOCxqFzvDgXCyTcTg6sdAAAAAA"; }; type = "public-key"; }; email = "my@email.com"; } Django Python Host auth_cred_json - {'id': 'JNMBbZF_PQM7O64RY_MXQqhAyKk', 'response': {'clientDataJSON': 'eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoidkhYcTdKTG05Z2dNU1BienNpZThFWUJsVW16V2N3WXlvOFBnT0FKMlR1b0VBbGVBbkQ0NGFNVDg3RG93YnZaZUNxLWxTdC1uNTFkUWJpVzgxNVhZRlEiLCJvcmlnaW4iOiJodHRwczovL2FuY2hvci1hd2F5LmNvbSJ9', 'signature': 'WJ3tJNMYfNST99x-EAdNDrnsUOCxqFzvDgXCyTcTg6sdAAAAAA', 'authenticatorData': 'MEYCIQDgVFINihy9nPuuRrZWkLPahEfLy3huCV9_seOuM5gSlgIhAP_99EVQjXhyJy37ccRxQenSxt7oPNrQ4VjVDSW5Ej8l'}, 'type': 'public-key', 'rawId': 'JNMBbZF_PQM7O64RY_MXQqhAyKk'} AuthorizationCredential generated by 'parse_authentication_credential_json' id='JNMBbZF_PQM7O64RY_MXQqhAyKk' raw_id=b'$\\xd3\\x01m\\x91\\x7f=\\x03;;\\xae\\x11c\\xf3\\x17B\\xa8@\\xc8\\xa9' response=AuthenticatorAssertionResponse( client_data_json=b'{ "type":"webauthn.get", "challenge":"vHXq7JLm9ggMSPbzsie8EYBlUmzWcwYyo8PgOAJ2TuoEAleAnD44aMT87DowbvZeCq-lSt-n51dQbiW815XYFQ", "origin":"https://anchor-away.com" }', authenticator_data=b"0F\\x02!\\x00\\xe0TR\\r\\x8a\\x1c\\xbd\\x9c\\xfb\\xaeF\\xb6V\\x90\\xb3\\xda\\x84G\\xcb\\xcbxn\\t_\\x7f\\xb1\\xe3\\xae3\\x98\\x12\\x96\\x02!\\x00\\xff\\xfd\\xf4EP\\x8dxr'-\\xfbq\\xc4qA\\xe9\\xd2\\xc6\\xde\\xe8<\\xda\\xd0\\xe1X\\xd5\\r%\\xb9\\x12?%", signature=b'X\\x9d\\xed$\\xd3\\x18|\\xd4\\x93\\xf7\\xdc~\\x10\\x07M\\x0e\\xb9\\xecP\\xe0\\xb1\\xa8\\\\\\xef\\x0e\\x05\\xc2\\xc97\\x13\\x83\\xab\\x1d\\x00\\x00\\x00\\x00', user_handle=None )
2
0
694
Feb ’24
kSecTrustResultProceed misbehave
"kSecTrustResultProceed indicates that the user has explicitly trusted a certificate." Problem: kSecTrustResultProceed returned from 'SecTrustEvaluate' for some users(733/million), while their cert chain contains non explicitly trusted certs: cert chain: ***.***.com Go Daddy Secure Certificate Authority - G2 Go Daddy Root Certificate Authority - G2 (Go Daddy is trusted on iOS, not explicitly trusted) I cannot reproduce this on my phone, but it does exist, for some users, including iOS 17. Any thoughts? SecTrustResultType res = kSecTrustResultInvalid; SecTrustEvaluate(secTrust, &res); if (res == kSecTrustResultUnspecified) { return YES; } if (res == kSecTrustResultProceed) { // some check... found this question return YES; } if (res != kSecTrustResultRecoverableTrustFailure) { return NO; } // some recover... return recovered;
2
0
331
Feb ’24
CommonCrypto swift module error in App
I'm working on an app that uses CommonCrypto. The app works perfectly well in my own computer, but when using the very same exe build in another computer it "quit unexpectedly". Suspecting that the issue could be on the said module, I commented out the few lines that requires the module and problem solved!. Now, as I need to use the module at the very beginning of the app, to perform certain security operations, I'm wondering what could I do to assure the module is included in the build, so the app may work in any other computer as well. This sounds weird, because I would had assumed either that the module was to be included in the build or if not, an error claiming the lack of it should have been produced. (within Xcode) what setting should I change when build the app for use in other computers, so to assure the operations that requires this module can be completed? Although this may not be relevant, I'm using swift 5, Xcode 15 (latest versions) and Sonoma 14.2.1
5
0
722
Feb ’24
Privacy manifest - API reasoning unavailable
Hi, We are a fraud detection and prevention company. We provide SDKs to customers to integrate with their applications. I wanted to clarify if we are required to provide the data collection details in the manifest files same question for the system APIs the reasons mentioned for the system APIs don't fit with our use case, how can we get the custom reasons added in case we need to mention those in the manifest.
0
0
240
Feb ’24