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

Discrepancy between documentation and the actual behavior
I think there's a slight discrepancy between what is being communicated in EndpointSecurity docs, and what is really happening. For example, consider the description of this event: https://developer.apple.com/documentation/endpointsecurity/es_event_type_t/es_event_type_notify_truncate?language=objc "ES_EVENT_TYPE_NOTIFY_TRUNCATE: An identifier for a process that notifies endpoint security that it is truncating a file." But, it seems that this event is fired up only when truncate(2) is called, not when process truncates a file (which can be done in lots of different ways). But the documentation doesn't even mention that it's only about the truncate(2) call, it's impossible to know. Another example: https://developer.apple.com/documentation/endpointsecurity/es_event_type_t/es_event_type_notify_copyfile?language=objc "ES_EVENT_TYPE_NOTIFY_COPYFILE: An identifier for a process that notifies endpoint security that it is copying a file." It seems that this event is only called when copyfile(3) syscall is called. But the docs doesn't mention that syscall at all. The wording suggests that the event should be emitted on every file copy operation, which is probably impossible to detect. I mean, I get that you'd like the docs to be "easy to digest", but I think that such working confuses people. They expect one thing, then they get confusing behavior from ES, because it doesn't match their expectations, and after reaching out to Apple they get concise and clear answer -- but it would be easier for everyone (including Apple devs) when this answer would be included directly in the official docs for the framework.
2
0
276
Oct ’24
iOS18 webView Client not authorized
Error launching process, description '未能完成操作。(com.apple.extensionKit.errorDomain错误2。)', reason '' GPU process (0x129000ab0) took 3.3203 seconds to launch WebContent process (0x1280180c0) took 5.3785 seconds to launch Failed to create extensionProcess for extension 'com.apple.WebKit.Networking' error: Error Domain=com.apple.extensionKit.errorDomain Code=2 "(null)" UserInfo={NSUnderlyingError=0x302e21b60 {Error Domain=RBSServiceErrorDomain Code=1 "Client not authorized" UserInfo={NSLocalizedFailureReason=Client not authorized, RBSPermanent=false}}}
1
0
162
Oct ’24
Whether non-Apple Store mac apps can use passkey?
Our desktop app for macos will be released in 2 channels appstore dmg package on our official website for users to download and install Now when we debug with passkey, we find that the package name of the appstore can normally arouse passkey, but the package name of the non-App Store can not arouse the passkey interface I need your help. Thank you
1
0
357
Oct ’24
How would you approach an Encryption Key being leaked?
I was curious as to the procedure for having an encryption key leaked and was hoping to have your opinions on how these two questions will be answered [if you were in the position]. Q1: Let's say, for instance, that you're making a social media network that stores private messages in a database network (such as Firebase) and uses basic encryption to store that data into an encrypted format (e.g., text message: "Hello Mous772!"; Firebase data: "deaErG5gao7J5qw/QI3EOA=="). But oh no! Someone got access to the encryption key used to encrypt hundreds of thousands of messages. You cannot simply delete thousands of messages because of this hacker, so how should you deal with this? This is where my question comes in. Is it possible to change the encryption key for all of the data if I am using the code system at the bottom of this question and using that code system to store encrypted data in Firebase? If so, how would you go about doing that? (Please use simple language; I'm not good with this stuff). Q2: What, in your opinion, is the best way to prevent this in the first place? I was told that a good solution was to store two sets of the same data; when one kegs it, we shut down the original and use the backup; however, this does not sound sustainable at all. I want to know what steps can be taken to ensure this never happens. [Please don't give me "Well... you can never *really hide these keys!" I'm well aware it's not possible to never have them leaked ever; I'm just looking for best practices only.] This is the encryption system we are using for this hypothetical app. // MARK: Value // MARK: Private private let key: Data private let iv: Data // MARK: - Initialzier init?(key: String, iv: String) { guard key.count == kCCKeySizeAES128 || key.count == kCCKeySizeAES256, let keyData = key.data(using: .utf8) else { debugPrint("Error: Failed to set a key.") return nil } guard iv.count == kCCBlockSizeAES128, let ivData = iv.data(using: .utf8) else { debugPrint("Error: Failed to set an initial vector.") return nil } self.key = keyData self.iv = ivData } // MARK: - Function // MARK: Public func encrypt(string: String) -> Data? { return crypt(data: string.data(using: .utf8), option: CCOperation(kCCEncrypt)) } func decrypt(data: Data?) -> String? { guard let decryptedData = crypt(data: data, option: CCOperation(kCCDecrypt)) else { return nil } return String(bytes: decryptedData, encoding: .utf8) } func crypt(data: Data?, option: CCOperation) -> Data? { guard let data = data else { return nil } let cryptLength = data.count + key.count var cryptData = Data(count: cryptLength) var bytesLength = Int(0) let status = cryptData.withUnsafeMutableBytes { cryptBytes in data.withUnsafeBytes { dataBytes in iv.withUnsafeBytes { ivBytes in key.withUnsafeBytes { keyBytes in CCCrypt(option, CCAlgorithm(kCCAlgorithmAES), CCOptions(kCCOptionPKCS7Padding), keyBytes.baseAddress, key.count, ivBytes.baseAddress, dataBytes.baseAddress, data.count, cryptBytes.baseAddress, cryptLength, &bytesLength) } } } } guard Int32(status) == Int32(kCCSuccess) else { debugPrint("Error: Failed to crypt data. Status \(status)") return nil } cryptData.removeSubrange(bytesLength..<cryptData.count) return cryptData } } //let password = "UserPassword1!" //let key128 = "1234567890123456" // 16 bytes for AES128 //let key256 = "12345678901234561234567890123456" // 32 bytes for AES256 //let iv = "abcdefghijklmnop" // 16 bytes for AES128 //let aes128 = AES(key: key128, iv: iv) //let aes256 = AES(key: key256, iv: iv) //let encryptedPassword128 = aes128?.encrypt(string: password) //aes128?.decrypt(data: encryptedPassword128) //let encryptedPassword256 = aes256?.encrypt(string: password) //aes256?.decrypt(data: encryptedPassword256)
3
0
192
Oct ’24
CryptoTokenKit accessible through a network
Hi, team. I am exploring and learning about CryptoTokenKit's capabilities. I would like to understand better what it means when the documentation says hardware tokens can be accessible through a network. How would that work? Is there an example? Is there more documentation about it available? What is the flow? Do we make a regular network request to fetch the keys, then create a Certificate or Password object, then store it with the regular persistence extension of CTK? So, it would be like using CryptoKit and the keychain but using hardware's security layer?
4
0
281
Oct ’24
ASWebAuthenticationSession Async/Await API
Is there any particular reason why ASWebAuthenticationSession doesn't have support for async/await? (example below) do { let callbackURL = try await webAuthSession.start() } catch { // handle error } I'm curious if this style of integration doesn't exist for architectural reasons? Or is the legacy completion handler style preserved in order to prevent existing integrations from breaking?
0
0
218
Oct ’24
List of Relay Servers for Passkeys
My organization routes all device traffic through a network security device that performs TLS intercept (SSL inspection). As might be expected, this breaks passkey Cross-Device Authentication (CDA) functionality, since the thumbprints don't match end-to-end between the authenticator (iPhone) and the client (laptop). As soon as I disable the VPN tunnel through our security device, the passkey login works as expected. The security team is willing to exclude the relay servers from SSL inspection, but we are unable to find a list of the relevant endpoints. Is there a list of Apple relay servers that are used for passkey tunnelling? We can review the network logs to find the traffic, but I'd prefer an authoritative list. For full context: we are using device-bound passkeys via Microsoft Authenticator to login to Entra but, as I understand it, the passkey is still handled via Apple's standard passkey infrastructure and APIs. Thanks!
0
0
129
Oct ’24
App Crash on Lock Screen During Biometrics Permission Prompt Using LAContext()
I am using LAContext(), canEvaluatePolicy, and evaluatePolicy in my project, and I've encountered a crash under a specific scenario. When the permission prompt appears asking, "Do you want to allow [App Name] to use biometrics in your app?" and the user locks the device without selecting "Allow" or "Don't Allow," the app crashes at that point. Has anyone else experienced this issue or tested this scenario? Any insights would be appreciated!
1
0
139
Oct ’24
Decrypt secp256r1
Hi, I try to decrypt some string. Does this code looks good? I get error: CryptoKit.CryptoKitError error 3. do { guard let encryptedData = Data(base64Encoded: cardNumber), let securityKeyData = Data(base64Encoded: securityKey), let ivData = Data(base64Encoded: iv), let privateKeyData = Data(base64Encoded: privateKey) else { throw NSError(domain: "invalid_input", code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid Base64 input."]) } let privateKey = try P256.KeyAgreement.PrivateKey(derRepresentation: privateKeyData) let publicKey = try P256.KeyAgreement.PublicKey(derRepresentation: securityKeyData) let sharedSecret = try privateKey.sharedSecretFromKeyAgreement(with: publicKey) let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey( using: SHA256.self, salt: Data(), sharedInfo: Data(), outputByteCount: 32 ) let encryptedDataWithoutTag = encryptedData.dropLast(16) let tagData = encryptedData.suffix(16) let nonce = try AES.GCM.Nonce(data: ivData) let sealedBox = try AES.GCM.SealedBox(nonce: nonce, ciphertext: encryptedDataWithoutTag, tag: tagData) let decryptedData = try AES.GCM.open(sealedBox, using: symmetricKey) resolve(decryptedCardNumber) } catch { print("Decryption failed with error: \(error.localizedDescription)") reject("decryption_error", "Decryption failed with error: \(error.localizedDescription)", nil) }
5
0
301
Oct ’24
SSO extension with Platform SSO token issues
Hi all. So, I built the platform SSO extension on a demo server I created and everything ran smoothly. I get the tokens at the end of the process. Now, I want to use the tokens when I trigger my SSO extension in my domain from Safari. I trigger my domain, get into the beginAuthorization method, get the request.loginManager?.ssoTokens and then want to return them to Safari by calling the request.complete method. But, no matter what complete method I call (complete(httpResponse: HTTPURLResponse, httpBody: Data?) or complete(httpAuthorizationHeaders: [String : String]) where I insert the Bearer token into the Authorization header, it will not drill down to Safari or my server. The headers I try to send back are not moving from the extension to Safari. Some knows why its happening? Thank you for any help or suggestion.
0
3
267
Oct ’24
Sicherheit App
Option 1: Kurz und prägnant "Hilfe in jeder Situation! Unsere App alarmiert schnell und unkompliziert die Rettungskräfte. Egal wo du bist, wir helfen dir in Notfällen." Option 2: Detaillierter "Schnelle Hilfe für alle! Mit unserer App hast du rund um die Uhr einen zuverlässigen Helfer an deiner Seite. Ob du selbst in Not bist oder Zeugen eines Unfalls werden – mit nur einem Klick alarmierst du die Rettungskräfte und erhältst wichtige Informationen. Funktioniert für iOS und Android." Option 3: Fokus auf die Zielgruppe "Alle" "Für jeden ein Lebensretter! Egal, ob jung oder alt, sportlich oder weniger beweglich – unsere App ist für alle gedacht, die in einer Notlage schnell Hilfe benötigen. Einfach, intuitiv und immer für dich da." Option 4: Betonung der Notfallfunktion "Dein persönlicher Notfallhelfer! In kritischen Situationen zählt jede Sekunde. Unsere App sorgt dafür, dass die Rettungskräfte schnellstmöglich bei dir sind. Perfekt für unterwegs, zu Hause oder am Arbeitsplatz." Option 5: Hervorhebung der Plattformunabhängigkeit "Hilfe ohne Grenzen! Unsere App ist für iOS und Android Geräte verfügbar und sorgt dafür, dass du immer und überall Hilfe bekommst. Egal, welches Smartphone du hast, wir sind für dich da." Möchtest du, dass ich einen Text entwerfe, der alle deine Punkte vereint? Oder hast du weitere Wünsche oder Vorstellungen?
0
0
274
Oct ’24
Swift how to add password to the `Passwords App`
I added a password to Keychain using Swift on macOS. All works well, and I can see it using Keychain Access, it is stored under iCloud -> Passwords. How can I see this password on the Passwords App. Is there something I need to do, maybe in Swift, to have this password in the Passwords App, not just in Keychain Access Note, I have turn on iCloud Keychain on my Mac: https://support.apple.com/en-us/109016
1
0
305
Oct ’24
Help! My computer shut of while I was trying to save my PN Key File
I am trying to finish my very first app. I went to save the PN key file and my computer shut off. I went to Certificates, Identifiers, and profiles and it says that I have reached the maximum allowed. I dont know what to do. I cant do anything with my app this is so stupid how could they make it so something like this was even possible. I am totally screwed. Please help me!
1
0
147
Oct ’24
Something odd with Endpoint Security & was_mapped_writable
I'm seeing some odd behavior which may be a bug. I've broken it down to a least common denominator to reproduce it. But maybe I'm doing something wrong. I am opening a file read-write. I'm then mapping the file read-only and private: void* pointer = mmap(NULL, 17, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); I then unmap the memory and close the file. After the close, eslogger shows me this: {"close":{"modified":false,[...],"was_mapped_writable":false}} Which makes sense. I then change the mmap statement to: void* pointer = mmap(NULL, 17, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0); I run the new code and and the close looks like: {"close":{"modified":false, [....], "was_mapped_writable":true}} Which also makes sense. I then run the original again (ie, with MAP_PRIVATE vs. MAP_SHARED) and the close looks like: {"close":{"modified":false,"was_mapped_writable":true,[...]} Which doesn't appear to be correct. Now if I just open and close the file (again, read-write) and don't mmap anything the close still shows: {"close":{ [...], "was_mapped_writable":true,"modified":false}} And the same is true if I open the file read-only. It will remain that way until I delete the file. If I recreate the file and try again, everything is good until I map it MAP_SHARED. I tried this with macOS 13.6.7 and macOS 15.0.1.
2
0
293
Oct ’24
Can't send email to Apple Private Relay
I am trying to send email from our internal server. We are using gmail as smtp client. Gmail is bound to a domain hosted on squarespace. I have all the required DNS records - DKIM, DMARC, SPF configured in squarespace. In the Apple Developer Portal, I have also added allowed domains and email addresses in the Sign In with Apple settings. SPF verification passed. The problem is that emails sent to @privaterelay.appleid.com are not reaching the final recipient. On our end, the emails are sent and there are no errors. In the email signature the DKIM domain and the domain in the From: address match completely. Domain on tools like mxtoolbox passes all checks. Also, there is no response from the gmail server that the email was not delivered. To all other emails the emails are being sent with no problems. Please help me figure this out, maybe I am missing something.
1
0
288
Oct ’24
Command line app doesn't prompt for a permission when it runs from from a terminal
I've made a simple command line app that requires Screen recording permission. When I ran it from Xcode, it prompts for a permission and once I allowed it from the settings, it runs well. #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;CoreGraphics/CGDisplayStream.h&gt; int main() { printf("# Start #\n"); if (CGPreflightScreenCaptureAccess()) { printf("# Permitted.\n"); } else { printf("# Not permitted.\n"); if (CGRequestScreenCaptureAccess() == false) { printf("# CGRequestScreenCaptureAccess() returning false\n"); } } size_t output_width = 1280; size_t output_height = 720; dispatch_queue_t dq = dispatch_queue_create("com.domain.screengrabber", DISPATCH_QUEUE_SERIAL); CGError err; CGDisplayStreamRef sref = CGDisplayStreamCreateWithDispatchQueue( 1, output_width, output_height, 'BGRA', NULL, dq, ^( CGDisplayStreamFrameStatus status, uint64_t time, IOSurfaceRef frame, CGDisplayStreamUpdateRef ref ) { printf("Got frame: %llu, FrameStatus:%d \n", time, status); } ); err = CGDisplayStreamStart(sref); if (kCGErrorSuccess != err) { printf("Error: failed to start streaming the display. %d\n", err); exit(EXIT_FAILURE); } while (true) { usleep(1e5); } CGDisplayStreamStop(sref); printf("\n\n"); return 0; } Now I want to execute this from terminal, so I went to the build folder and typed the app name. cd /Users/klee/Library/Developer/Xcode/DerivedData/ScreenStreamTest-ezddqbkzhndhakadslymnvpowtig/Build/Products/Debug ./ScreenStreamTest But I am getting following output without any prompt for permission. # Start # # Not permitted. # CGRequestScreenCaptureAccess() returning false Error: failed to start streaming the display. 1001 Is there a something I need to consider for this type of command line app?
1
0
206
Oct ’24
kSecAttrAccessGroup and kSecAttrAccessGroupToken
Hi, team. So, I'm working on reading certificates from the keychain that have been stored or saved by other apps into it. I understand that kSecAttrAccessGroupToken allows us to achieve that. It is a requirement to use com.apple.token group in the entitlements file. Having done that, I cannot store SecSertificates into the keychain, and into the security group. I can do it without the security group, but after adding in the dictionary the kSecAttrAccessGroup: kSecAttrAccessGroupToken, I can no longer add certificates. I get the famous -34018. No entitlement found. However, when I try to read certificates in the same access group, I do not get a -34018 error back. I instead get a -25300, which I understand means no keychain item was found in this access group. How can this be happening? Reading, the entitlement works, writing does not. Here are my queries: For adding: let addQuery = [ kSecClass: kSecClassCertificate, kSecValueRef: secCertificate as Any, kSecAttrLabel: certificateName, kSecAttrAccessGroup: kSecAttrAccessGroupToken ] as [CFString: Any] let status = SecItemAdd(addQuery as CFDictionary, nil) For reading: var item: CFTypeRef? let query = [ kSecClass: kSecClassCertificate, kSecMatchLimit: kSecMatchLimitAll, kSecReturnRef: kCFBooleanTrue as Any, kSecAttrAccessGroup: kSecAttrAccessGroupToken ] as [CFString: Any] let status = SecItemCopyMatching(query as CFDictionary, &amp;item)
4
0
285
Oct ’24