We’ve noticed an unexpected behavior in our production iOS app where the UIDevice.current.identifierForVendor value occasionally changes, even though:
The app is distributed via the App Store (not TestFlight or Xcode builds)
We do not switch provisioning profiles or developer accounts
No App Clips, App Thinning, or other advanced features are in use
There’s no manual reinstall or device reset in the scenarios observed (as per user feedback)
Any insights or confirmations would be much appreciated.
Thanks!
General
RSS for tagPrioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi! I am trying to run the demo app(SampleEndpointApp) from the WWDC2020 presentation(link).
Here are the steps I followed in order to run the app:
I submitted a request for the Endpoint Security entitlement and got the approval from the Apple Support team.
Created an identifier and assigned Endpoint Security capability.
Updated the Bundle Identifier in ViewController.m and in the Extension target.
Built and copied the app bundle to /Application folder.
Ran the app, clicked "Install Extension" and got the confirmation message that everything went well.
Looking into the logs, I see the following :
(libEndpointSecurity.dylib) Failed to open service: 0xe00002d8: Caller lacks TCC authorization for Full Disk Access
I keep getting the same message even after granting SampleEndpointApp Full Disk Access in Privacy & Security.
System : macOS Sequoia 15.1.1
Could you please assist me with this issue?
Andrei
I have my custom Authplugin implemented at login (system.login.console), and I want to remove password requirement validation/authentication from system.login.console authorization right. Do you see any functionality loss in completely removing password need at login. And is there any reference which can help me here to acheive this?
Hi,
I'm working on developing my own CryptoTokenKit (CTK) extension to enable codesign with HSM-backed keys. Here's what I’ve done so far:
The container app sets up the tokenConfiguration with TKTokenKeychainCertificate and TKTokenKeychainKey.
The extension registers successfully and is visible via pluginkit when launching the container app.
The virtual smartcard appears when running security list-smartcards.
The certificate, key, and identity are all visible using security export-smartcard -i [card].
However, nothing appears in the Keychain.
After adding logging and reviewing output in the Console, I’ve observed the following behavior when running codesign:
My TKTokenSession is instantiated correctly, using my custom TKToken implementation — so far, so good.
However, none of the following TKTokenSession methods are ever called:
func tokenSession(_ session: TKTokenSession, beginAuthFor operation: TKTokenOperation, constraint: Any) throws -> TKTokenAuthOperation
func tokenSession(_ session: TKTokenSession, supports operation: TKTokenOperation, keyObjectID: TKToken.ObjectID, algorithm: TKTokenKeyAlgorithm) -> Bool
func tokenSession(_ session: TKTokenSession, sign dataToSign: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data
func tokenSession(_ session: TKTokenSession, decrypt ciphertext: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data
func tokenSession(_ session: TKTokenSession, performKeyExchange otherPartyPublicKeyData: Data, keyObjectID objectID: Any, algorithm: TKTokenKeyAlgorithm, parameters: TKTokenKeyExchangeParameters) throws -> Data
The only relevant Console log is:
default 11:31:15.453969+0200 PersistentToken [0x154d04850] invalidated because the client process (pid 4899) either cancelled the connection or exited
There’s no crash report related to the extension, so my assumption is that ctkd is closing the connection for some unknown reason.
Is there any way to debug this further?
Thank you for your help.
Hi all,
I’m building a macOS-native C++ trading bot, compiled via Xcode. It sends REST API requests to a crypto exchange (Bitvavo) that require HMAC-SHA256 signatures using a pre-sign string (timestamp + method + path + body) and an API secret.
Here’s the issue:
• The exact same pre-sign string and API secret produce valid responses when signed using Python (hmac.new(secret, msg, hashlib.sha256)),
• But when I generate the HMAC signature using C++ (HMAC(EVP_sha256, ...) via OpenSSL), the exchange returns an invalid signature error.
Environment:
• Xcode 15.3 / macOS 14.x
• OpenSSL installed via Homebrew
• HMAC test vectors match Python’s output for basic strings (so HMAC lib seems correct)
Yet when using the real API keys and dynamic timestamped messages, something differs enough to break verification — possibly due to UTF-8 encoding, memory alignment, or newline handling differences in the Xcode C++ runtime?
Has anyone experienced subtle differences between Python and C++ HMAC-SHA256 behavior when compiled in Xcode?
I’ve published a GitHub repo for reproducibility:
🔗 https://github.com/vanBaardewijk/bitvavo-cpp-signature-test
Thanks in advance for any suggestions or insights.
Sascha
I am working on adding RFC4217 Secure FTP with TLS by extending Mike Gleason's classic libncftp client library. I refactored the code to include an FTP channel abstraction with FTP channel abstraction types for TCP, TLS, and TCP with Opportunistic TLS types. The first implementation of those included BSD sockets that libncftp has always supported with the clear TCP channel type.
I first embarked on extending the sockets implementation by adding TCP, TLS, and TCP with Opportunistic TLS channel abstraction types against the new, modern Network.framework C-based APIs, including using the “tricky” framer technique to employ a TCP with Opportunistic TLS FTP channel abstraction type to support explicit FTPS as specified by RFC4217 where you have to connect first in the clear with TCP, request AUTH TLS, and then start TLS after receiving positive confirmation. That all worked great.
Unfortunately, at the end of that effort, I discovered that many modern FTPS server implementations (vsftpd, pure-ftpd, proftpd) mandate TLS session reuse / resumption across the control and data channels, specifying the identical session ID and cipher suites across the control and data channels. Since Network.framework lacked a necessary and equivalent to the Secure Transport SSLSetPeerID, I retrenched and rewrote the necessary TLS and TCP with Opportunistic TLS FTP channel abstraction types using the now-deprecated Secure Transport APIs atop the Network.framework-based TCP clear FTP channel type abstraction I had just written.
Using the canonical test server I had been using throughout development, test.rebex.net, this Secure Transport solution seemed to work perfectly, working in clear, secure-control-only, and secure-control+data explicit FTPS operation.
I then proceeded to expand testing to include a broad set of Microsoft FTP Service, pure-ftpd, vsftpd, proftpd, and other FTP servers identified on the Internet (a subset from this list: https://gist.github.com/mnjstwins/85ac8348d6faeb32b25908d447943300).
In doing that testing, beyond test.rebex.net, I was unable to identify a single (among hundreds), that successfully work with secure-control+data explicit FTPS operation even though nearly all of them work with secure-control-only explicit FTPS operation.
So, I started regressing my libncftp + Network.framework + Secure Transport implementation against curl 8.7.1 on macOS 14.7.2 “Sonoma":
% which curl; `which curl` --version
/usr/bin/curl
curl 8.7.1 (x86_64-apple-darwin23.0) libcurl/8.7.1 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.12 nghttp2/1.61.0
Release-Date: 2024-03-27
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe UnixSockets
I find that curl (also apparently written against Secure Transport) works in almost all of the cases my libncftp does not. This is a representative example:
% ./samples/misc/ncftpgetbytes -d stderr --secure --explicit --secure-both ftps://ftp.sjtu.edu.cn:21/pub/README.NetInstall
which fails in the secure-control+data case with errSSLClosedAbort on the data channel TLS handshake, just after ClientHello, attempts whereas:
% curl -4 --verbose --ftp-pasv --ftp-ssl-reqd ftp://ftp.sjtu.edu.cn:21/pub/README.NetInstall
succeeds.
I took an in-depth look at the implementation of github.com/apple-oss-distributions/curl/ and git/github.com/apple-oss-distributions/Security/ to identify areas where my implementation was, perhaps, deficient relative to curl and its curl/lib/vtls/sectransp.c Secure Transport implementation. As far as I can tell, I am doing everything consistently with what the Apple OSS implementation of curl is doing. The analysis included:
SSLSetALPNProtocols
Not applicable for FTP; only used for HTTP/2 and HTTP/3.
SSLSetCertificate
Should only be relevant when a custom, non-Keychain-based certificate is used.
SSLSetEnabledCiphers
This could be an issue; however, the cipher suite used for the data channel should be the same as that used for the control channel. curl talks about disabling "weak" cipher suites that are known-insecure even though the default suites macOS enables are unlikely to enable them.
SSLSetProtocolVersionEnabled
We do not appear to be getting a protocol version negotiation error, so this seems unlikely, but possible.
SSLSetProtocolVersionMax
We do not appear to be getting a protocol version negotiation error, so this seems unlikely, but possible.
SSLSetProtocolVersionMin
We do not appear to be getting a protocol version negotiation error, so this seems unlikely, but possible.
SSLSetSessionOption( , kSSLSessionOptionFalseStart)
curl does seem to enable this for certain versions of macOS and disables it for others. Possible.
Running curl with the --false-start option does not seem to make a difference.
SSLSetSessionOption( , kSSLSessionOptionSendOneByteRecord)
Corresponds to "*****" which seems defaulted and is related to an SSL security flaw when using CBC-based block encryption ciphers, which is not applicable here.
Based on that, further experiments I attempted included:
Disable use of kSSLSessionOptionBreakOnServerAuth: No impact
Assert use of kSSLSessionOptionFalseStart: No impact
Assert use of kSSLSessionOptionSendOneByteRecord: No impact
Use SSLSetProtocolVersionMin and SSLSetProtocolVersionMax in various combinations: No impact
Use SSLSetProtocolVersionEnabled in various combinations: No impact
Forcibly set a single cipher suite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, known to work with a given server): No impact
Employ a SetDefaultCipherSuites function similar to what curl does (filtering out “weak” cipher suites): No impact
Notably, I can never coax a similar set of cipher suites that macOS curl does with that technique. In fact, it publishes ciphers that aren’t even in <Security/CipherSuite.h> nor referenced by github.com/apple-oss-distributions/curl/curl/lib/vtls/sectransp.c.
Assert use of kSSLSessionOptionAllowRenegotiation: No impact
Assert use of kSSLSessionOptionEnableSessionTickets: No impact
Looking at Wireshark, my ClientHello includes status_request, signed_certificate_timestamp, and extended_master_secret extensions whereas macOS curl's never do--same Secure Transport APIs. None of the above API experiments seem to influence the inclusion / exclusion of those three ClientHello additions.
Any suggestions are welcomed that might shine a light on what native curl has access to that allows it to work with ST for these FTP secure-control+data use cases.
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.
Attempting to DECRYPT a cipher message using the Apple API SecKeyCreateDecryptedData(privateKey, .rsaEncryptionOAEPSHA256, encryptedMessage). Decryption ALWAYS fails for every algorithm.
SecKeyCreateDecryptedDataWithParameters Error: `Domain=NSOSStatusErrorDomain Code=-50 "algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key <SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150>" UserInfo={numberOfErrorsDeep=0, NSDescription=algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key <SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150>}`
Decryption failed: SecKeyCreateDecryptedData returned nil.
Error: One or more parameters passed to a function were not valid.
When checking with SecKeyIsAlgorithmSupported(privateKey, .decrypt, <ANYalgorithm>) all algorithms fail. Btw - The privateKey does support decryption when retrieving the attributes.
Important to know:
The private key is a reference to an external private key placed in the iOS Keychain via a 3rd party CryptoTokenKit Extension app. When I perform, the SecKeyCreateSignature(...) and pass in the SAME privateKey reference, the OS automatically calls the 3rd party app to perform a successful signing with the private key that reside on a YubiKey.
Here's my code for obtaining the private key reference from an Identity:
func getKeyPairFromIdentity() -> (privateKey: SecKey, publicKey: SecKey)? {
let query = NSDictionary(
dictionary: [
kSecClass as String: kSecClassIdentity,
kSecAttrTokenID as String: self.tokenID!,
kSecReturnRef as String: kCFBooleanTrue as Any
]
)
var identityRef: CFTypeRef?
let status = SecItemCopyMatching(query, &identityRef)
if status == errSecSuccess, let identity = identityRef {
var privateKeyRef: SecKey?
let keyStatus = SecIdentityCopyPrivateKey(identity as! SecIdentity, &privateKeyRef)
if keyStatus == errSecSuccess, let privateKey = privateKeyRef {
let publicKey = SecKeyCopyPublicKey(privateKey)
if let publicKey = publicKey {
print("Private and public keys extracted successfully.")
return (privateKey, publicKey)
} else {
print("Failed to extract public key from private key.")
return nil
}
} else {
print("SecIdentityCopyPrivateKey: Private key not found error: \(keyStatus)")
return nil
}
} else {
print("SecIdentity not found or error: \(status)")
return nil
}
}
I'm trying to add a generic password to the keychain and get back the persistent ID for it, and give it .userPresence access control. Unfortunately, if I include that, I get paramError back from SecItemAdd. Here's the code:
@discardableResult
func
set(username: String, hostname: String?, password: String, comment: String? = nil)
throws
-> PasswordEntry
{
// Delete any existing matching password…
if let existing = try? getEntry(forUsername: username, hostname: hostname)
{
try deletePassword(withID: existing.id)
}
// Store the new password…
var label = username
if let hostname
{
label = label + "@" + hostname
}
var item: [String: Any] =
[
kSecClass as String : kSecClassGenericPassword,
kSecAttrDescription as String : "TermPass Password",
kSecAttrGeneric as String : self.bundleID.data(using: .utf8)!,
kSecAttrLabel as String : label,
kSecAttrAccount as String : username,
kSecValueData as String : password.data(using: .utf8)!,
kSecReturnData as String : true,
kSecReturnPersistentRef as String: true,
]
if self.synchronizable
{
item[kSecAttrSynchronizable as String] = kCFBooleanTrue!
}
if let hostname
{
item[kSecAttrService as String] = hostname
}
if let comment
{
item[kSecAttrComment as String] = comment
}
// Apply access control to require the user to prove presence when
// retrieving this password…
var error: Unmanaged<CFError>?
guard
let accessControl = SecAccessControlCreateWithFlags(nil,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
.userPresence,
&error)
else
{
let cfError = error!.takeUnretainedValue() as Error
throw cfError
}
item[kSecAttrAccessControl as String] = accessControl
item[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
var result: AnyObject!
let status = SecItemAdd(item as CFDictionary, &result)
try Errors.throwIfError(osstatus: status)
load()
guard
let secItem = result as? [String : Any],
let persistentRef = secItem[kSecValuePersistentRef as String] as? Data
else
{
throw Errors.malformedItem
}
let entry = PasswordEntry(id: persistentRef, username: username, hostname: hostname, password: password, comment: comment)
return entry
}
(Note that I also tried it omitting kSecAttrAccessible, but it had no effect.)
This code works fine if I omit setting kSecAttrAccessControl.
Any ideas? TIA!
Topic:
Privacy & Security
SubTopic:
General
Hello, I have created an app for both iOs and Android where upon speaking two trigger words, the listening app sends a text and then calls to an inputted designated phone contact. The Android version works perfectly. The iOs version also works perfectly but the iOs app emiits a PopUp for each, the text and then the call asking "Do you really want to send the text -or- make the call". Basically, I input the contact info and I spoke the trigger words. So, yes I want to send the text and make the call. So, I have to click the two PopUps then the device sends and calls.
Is there a way to suppress the PopUps in any way? The app is designed for emergencies. So, a dely to anser a popup is not at all good.
Maybe by telling the device to allow auto calls and texts from my app?
Any and all help on this issue will be very welcomed...
Thanks :)
I’d like to confirm something regarding the hosting of the apple-app-site-association (AASA) file.
We have a server that publicly hosts the AASA file and is accessible globally. However, this server sits behind an additional security layer (a security server/reverse proxy).
My question is:
Will this security layer affect Apple’s ability to access and validate the AASA file for Universal Links or App Clips?
Are there specific requirements (e.g. headers, redirects, TLS versions, etc.) that we need to ensure the security server does not block or modify?
Any guidance or best practices would be appreciated.
Thanks!
Has anyone here encountered this? It's driving me crazy.
It appears on launch.
App Sandbox is enabled.
The proper entitlement is selected (com.apple.security.files.user-selected.read-write)
I believe this is causing an issue with app functionality for users on different machines.
There is zero documentation across the internet on this problem.
I am on macOS 26 beta. This error appears in both Xcode and Xcode-beta.
Please help!
Thank you,
Logan
I'm trying to develop a GUI app on macOS that takes control of the screen so that user must perform certain actions before regaining control of the desktop. I don't want the user to be able to kill the process (for example via an "assassin" shell script that looks for the process and terminates it with kill).
Based on this post it is not possible to create an unkillable process on macOS.
I'm wondering, however, if it's possible to run the GUI process in root (or with other escalated privileges) such that the logged in user cannot kill it. So it's killable, but you need privileges above what the logged in user has (assuming they are not root). I'm not worried about a root user being able to kill it.
Such an app would run in a managed context. I've played around with Service Background Tasks, but so far haven't found what I'm looking for.
I'm hoping someone (especially from Apple) might be able to tell me if this goal is even achievable with macOS Sequoia (and beyond).
I am new to swift development, and it's possible that I'm missing something fundamental/obvious. If so, I apologize in advance. My team is developing an application for iPadOS using SwiftUI, and I'm trying to accomplish something similar to what the original inquirer is asking for in this thread: https://developer.apple.com/forums/thread/725152. The only difference is that I'm trying to use a PIV smart card to achieve authentication to a server rather than digitally sign a document.
Unfortunately, I'm getting stuck when attempting to run the list() function provided in the accepted answer to the post mentioned above. When attempting to call SecItemCopyMatching(), I'm getting a -34018 missing entitlement error. I've attempted to add the com.apple.token to my app's keychain-access-groups entitlements, but this does not resolve the issue. I have checked the entitlements in my built app, per the recommendation in the troubleshooting guide here: https://developer.apple.com/forums/thread/114456. The entitlement for com.apple.token is indeed present in the plist. Based on other documentation I've read, however, it seems that the explicit declaration of com.apple.token should not even be required in the entitlements.
Is there something obvious that I'm missing here that would prevent my app from accessing the token access group?
I have a small command-line app I've been using for years to process files. I have it run by an Automator script, so that I can drop files onto it. It stopped working this morning.
At first, I could still run the app from the command line, without Automator. But then after I recompiled the app, now I cannot even do that. When I run it, it's saying 'zsh: killed' followed by my app's path. What is that?
The app does run if I run it from Xcode.
How do I fix this?
Topic:
Privacy & Security
SubTopic:
General
In one of my apps I would like to find out if users have their device set up to authenticate with their Apple Watch.
According to the documentation (https://developer.apple.com/documentation/localauthentication/lapolicy/deviceownerauthenticationwithcompanion) this would be done by evaluating the LAPolicy like this:
var error: NSError?
var canEvaluateCompanion = false
if #available(iOS 18.0, *) {
canEvaluateCompanion = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithCompanion, error: &error)
}
But when I run this on my iPhone 16 Pro (iOS 18.5) with a paired Apple Watch SE 2nd Gen (watchOS 11.5) it always returns false and the error is -1000 "No companion device available". But authentication with my watch is definitely enabled, because I regularly unlock my phone with the watch.
Other evaluations of using biometrics just works as expected.
Anything that I am missing?
In some crashlog files, there are additional pieces of information related to codesigning.
I can understand what most of themcorresponds to (ID, TeamID, Flags, Validation Category). But there is one I have some doubt about: Trust Level.
As far as I can tell (or at least what Google and other search engines say), this is an unsigned 32 bit integer that defines the trust level with -1 being untrusted, 0, being basically an Apple executable and other potential bigger values corresponding to App Store binaries, Developer ID signature, etc.
Yet, I'm not able to find a corresponding detailed documentation about this on Apple's developer website.
I also had a look at the LightweightCodeRequirements "include" file and there does not seem to be such a field available.
[Q] Is there any official documentation listing the different values for this trust level value and providing a clear description of what it corresponds to?
For security reasons, my application needs to prohibit external devices. If it is determined that the current phone is connected to any external devices, including non MFI authenticated devices, the app will exit. Please tell me how to do it? Thanks for your help.
Hi,
I am using CryptoKit in my app. I am getting an error sometimes with some users. I log the description to Firebase but I am not sure what is it exactly about.
CryptoKit.CryptoKitError error 2
CryptoKit.CryptoKitError error 3
I receive both of these errors. I also save debug prints to a log file and let users share them with me. Logs are line-by-line encrypted but after getting these errors in the app also decryption of log files doesn't work and it throws these errors too.
I couldn't reproduce the same error by myself, and I can't reach the user's logs so I am a little blind about what triggers this.
It would be helpful to understand what these errors mean.
Thanks
We are working with an iOS app where we have enabled the “Generate Debug Symbols” setting to true in Xcode. As a result, the .dSYM files are generated and utilized in Firebase Crashlytics for crash reporting.
However, we received a note in our Vulnerability Assessment report indicating a potential security concern. The report mentions that the .ipa file could be reverse-engineered due to the presence of debug symbols, and that such symbols should not be included in a released app. We could not find any security-related information about this flag, “Generate Debug Symbols,” in Apple’s documentation.
Could you please clarify if enabling the “Generate Debug Symbols” flag in Xcode for a production app creates any security vulnerabilities, such as the one described in the report?
The report mentions the following vulnerability: TEST-0219: Testing for Debugging Symbols
The concern raised is that debugging symbols, while useful for crash symbolication, may be leveraged to reverse-engineer the app and should not be present in a production release.
Your prompt confirmation on this matter would be greatly appreciated. Thank you in advance for your assistance.