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

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
768
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
930
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
543
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
908
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
426
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
601
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.3k
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
704
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
334
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
739
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
245
Feb ’24
Не приходят проверочный код с Alibaba.com
Добрый день! Я создал аккаунт на Alibaba.com с помощью AppleID, при регистрации был выдан подменный адрес почты @privaterelay.appleid.com, при попытке подтвердить почту, письма не пересылаются на мою основную почту.
1
0
685
Feb ’24
Using kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
After a pen test it has been suggested we use kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly for keychain accessibility. It is currently using kSecAttrAccessibleAfterFirstUnlockValue We only store name, email, sms etc in our keychain but I've been asked to explore how much effort this would be My initial concern is what happens to users without a passcode? Is there a way to enforce this for users with a passcode but fallback to something else for other users? Thanks
1
0
466
Mar ’24
Understanding the List of 3rd Party SDKs that need Updates
Hey everyone, Was having a look into this article posted by Apple. I noticed that one of the SDKs I use - FirebaseMessaging - is included on that list. Having a look into the SDK's repository, I noticed that the Firebase team is already addressing the issue, as this PR shows. But, if you look at that SDK's PrivacyInfo.xcprivacy file, the NSPrivacyAccessedAPITypes property has no value associated with it. Apple clearly states that APIs that use required reason APIs are the ones that need to be updated until Sprint 2024. FirebaseMessaging looks like it doesn't, so why is it included on that list? Looking forward to your feedback.
0
0
508
Mar ’24
Is the GLKit library Apple's?
Hi. My team is still using GLKit. I have no choice but to keep using it to support non-iOS products as well. (We don't have many developers.) While researching 'Privacy Manifest', I found out that the third party library needs to add 'PrivacyInfo'. I confirmed on Xcode that GLKit is Apple SDKs. Does this mean it's not a third party library? Is using GLKit not related to 'Privacy Manifest'?
1
0
718
Mar ’24
Sharing Files and Photos into an App
I had a couple of questions someone could help me with, as I’m trying to do a little research for my team before they do a bunch of coding. We’re building an anywhere-to-anywhere encrypted file transfer app and wrestling currently with our share functionality. Currently, our users log into their app on their phone, and: within the application use a file picker to select files/photos and then select a destination that they pick from a permission-ed list. However, we really would like to also add the workflow where the user opens the photos or files app, finds a picture/file and then uses the share functionality to pass the object into the application, then The application launches, allowing the user to log into the app, then they pick from a list of permission-ed drop targets within the app and send the object In doing some research this morning regarding sharing files/pictures within our application, I found this thread Eskimo had more or less advised against what we intended to do: https://developer.apple.com/forums/thread/114485 We don’t want to save session tokens because of security concerns; we’re concerned primarily with third-party actors (governments primarily) having access to encryption keys. Is there a best-practice way for my team to open the app we're building and then passing the files/photos into our application? Does anyone have any advice on how to securely launch the application and pass the file/pic into the app given the constraints? Thanks!
1
0
459
Mar ’24
How to Create SecKeys from Data and Decrypt?
I am trying to communicate with a Java server over TCP, but I'm having issues trying to make the data secure in transit using RSA and AES. The server creates an AES key, encodes it in utf8, and sends it to the IOS Client, where it should be decoded back into a byte array as a Data object. Then, Using the Cryptokit framework, I try to create a SecKey object from it. I am stumped when trying to do so, though: func createSecKeyFromAESKeyData(aesKeyData: Data) -&gt; SecKey? { // Define the key attributes let keyAttributes: [CFString: Any] = [ kSecAttrKeyClass: kSecAttrKeyClassSymmetric, kSecAttrKeySizeInBits: 128, kSecAttrIsPermanent: false ] // Convert the AES key data into a SecKey object var error: Unmanaged&lt;CFError&gt;? guard let key = SecKeyCreateWithData(aesKeyData as CFData, keyAttributes as CFDictionary, &amp;error) else { if let error = error { print("Error creating SecKey: \(error.takeRetainedValue() as Error)") } else { print("Unknown error creating SecKey") } return nil } return key } Despite setting up my key attribute dictionary with the correct information (AES_128_GCM_SHA256, 128 bits, impermanent) based on how I generate it in the Java code, I keep getting a runtime error at the SecKeyCreateWithData call stating "Unsupported symmetric key type: 4865". I am unsure what this means and how to fix it as there doesn't seem to be any information on it online. If it helps, the Java code is using AES GCM with no padding, and we have confirmed that the data being sent is indeed 128 bits. How can I take this byte array and create a SecKey from it properly so we can pass secure data? Similarly, I have also tried using RSA encryption for some data, but with this method, I generate the key pair on the iOS client and send the parts of the public key to the Java server where it (seemingly correctly) created the cipher from the passed data. However, trying to send anything encrypted back resulted in "RSAdecrypt wrong input (err -27)" when decrypting: func decryptAESKey(encryptedKeyData: Data, privateKey: SecKey) -&gt; Data? { // Decrypt the received AES key using the private key var error: Unmanaged&lt;CFError&gt;? guard let decryptedKeyData = SecKeyCreateDecryptedData(privateKey, .rsaEncryptionOAEPSHA256, encryptedKeyData as CFData, &amp;error) as Data? else { print("Error decrypting AES key:", error!.takeRetainedValue() as Error) return nil } return decryptedKeyData } Any assistance in figuring out how to properly use SecKeys in these ways would be greatly appreciated. Additionally, the relevant Java code can be provided if necessary.
1
0
854
Mar ’24
Conditions under which a JWT client token expires
In order to use Sign in with Apple, I issued a JWT client according to the instructions and was able to connect without any problems, but suddenly an INVALID_CLIENT error started to occur. The error was resolved by re-obtaining the JWT client token and resetting it. The validity period of the JWT client token is 6 months and it has not expired yet, but I would like to know why I am getting an INVALID_CLIENT error.
1
0
377
Mar ’24
I'm trying to incorporate Sign-In with Apple for my Swift Application
I am getting an error "Cannot create a iOS App Development provisioning profile for "TheSwiftUIWay.login". Personal development teams, including "Cyril John", do not support the Sign in with Apple capability" I have created a developer account but I didnt enroll in the developer program. Am I able to use Sign-In with Apple with the free version of the Apple Developer Account? If so, can you please give me some directions on how I can fix this error?
1
0
566
Mar ’24
Multiple problems with ES_EVENT_TYPE_NOTIFY_DUP
Hello, 3 questions regarding Endpoint Security Framework: Does ESF support tracing the dup2(2) function? There is the ES_EVENT_TYPE_NOTIFY_DUP event, but it seems that it only reports dup(2), not dup2(2)? Does ESF support tracing the dup(2), and close(2) calls, if the file descriptor passed to these functions refer to a pipe handle instead of a file handle? If not, do you have any plans of extending the support for pipes as well? Could the es_event_dup_t structure support reporting which file handle has been duplicated into which value (source file descriptor value, and target file descriptor value)? Currently this structure only supports the "target" file object, without any information which file descriptor has been cloned into which file descriptor, which is not helpful at all. For example, if we open file A and we get fd1, then open the same file A and we get fd2, then perform dup(fd1), then with ESF it seems that it's impossible to tell if we've duplicated fd1 or fd2. Also this model doesn't support dup2(2) usage at all.
4
0
729
Mar ’24