Hello,
It is possible to restrict access to Desktop or Documents folder with TCC for a given application in macOS Preferences.
For example Terminal is not allowed to access Documents folder. But i have see it is possible to write files or to create directory from Terminal !
I don't understand this behaviour. Is there a particular reason ?
Thanks
Security
RSS for tagSecure the data your app manages and control access to your app using the Security framework.
Posts under Security tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I am new to security framework.
I want to access items only in dynamic keychain for smartCards. And just user keychains in case of some other scenario.
But SecKeychainOpen,SecKeychainGetPath and SecKeychainCopyDomainSearchList are deprecated. How do I make sure the secItemCopyMatching only looks for items in specific type of keychain.
Hello,
I have an encrypted dmg file containing a secret file.
When a user want's to see the secret, he must mount the dmg and provide password.
When the dmg is mounted, every user connected to the computer can see the secret file ! And i don't want this.
Is there a way to open a dmg file with swift language, without mounting it ?
Thanks
Hello, I am working on simple task, i have a JWT and I need to verify it's signature.
My sample data:
JWT
eyJhbGciOiJFUzI1NiIsImtpZCI6IjhEWVpUTFRPVUtNSjdUU0w4SFZVVTlUVEdXMV9NTVVSSURJV1JUVE0iLCJ0eXAiOiJKV1QifQ.eyJub25jZSI6Indkd2R3ZHdkIiwiZGF0ZVRpbWUiOiIyMDIzLTEwLTEzVDEyOjQ4OjQwWiJ9.nWBfRne9VOKV4NGt32gWtoA5fUKzu0RzkhUYSYwUA7cvalsABUcWrpEk0fhztPZDK7KrDF8P2Pquhoxq4p-FUg
Public key (JWK)
{
"kid": "8DYZTLTOUKMJ7TSL8HVUU9TTGW1_MMURIDIWRTTM",
"use": "sig",
"kty": "EC",
"alg": "ES256",
"crv": "P-256",
"x": "8dyzTlToUkMJ7tsl8HVuU9tTGw1_mmuridIWrttMRCs",
"y": "AVqGlqJ88QgP_uVLea7gIUnA-p9iYwnJyYt7o-uH4oU"
}
When you put the data to the [https://jwt.io] you get "Signature Verified" message. So the data should be ok.
I have implementation in Objective-C, but i get this weird error message when the SecKeyVerifySignature is called.
Here is my code:
#import <Cocoa/Cocoa.h>
#import <CommonCrypto/CommonDigest.h>
NSString* base64StringWithPadding(NSString *encodedString) {
NSString* stringTobeEncoded = [[encodedString stringByReplacingOccurrencesOfString:@"-" withString:@"+"]
stringByReplacingOccurrencesOfString:@"_" withString:@"/"];
int paddingCount = encodedString.length % 4;
for (int i = 0; i < paddingCount; i++) {
stringTobeEncoded = [stringTobeEncoded stringByAppendingString:@"="];
}
return stringTobeEncoded;
}
SecKeyRef restorePublicKey(NSString *x, NSString *y) {
NSString *xBase64Padd = base64StringWithPadding(x);
NSString *yBase64Padd = base64StringWithPadding(y);
NSData *xData = [[NSData alloc] initWithBase64EncodedString:xBase64Padd
options:kNilOptions]; //32bytes
NSData *yData = [[NSData alloc] initWithBase64EncodedString:yBase64Padd
options:kNilOptions]; //32bytes
NSMutableData *publicKeyData = [NSMutableData data];
// Append the constant byte '04' to indicate uncompressed format
const unsigned char uncompressedByte = 0x04;
[publicKeyData appendBytes:&uncompressedByte length:1];
// Append the X-coordinate and Y-coordinate
[publicKeyData appendData:xData];
[publicKeyData appendData:yData];
NSDictionary *keyAttributes = @{
(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom,
(id)kSecAttrKeyClass: (id)kSecAttrKeyClassPublic,
(id)kSecAttrKeySizeInBits: @256,
(id)kSecAttrIsPermanent:@NO
};
CFErrorRef error = NULL;
SecKeyRef publicKeyRef =
SecKeyCreateWithData(
(__bridge CFDataRef)publicKeyData,
(__bridge CFDictionaryRef)keyAttributes,
&error
);
if(!publicKeyRef) {
NSError *err = CFBridgingRelease(error);
NSLog(@"%@", err.description);
}
return publicKeyRef;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSDictionary *jwk =
@{
@"kid": @"8DYZTLTOUKMJ7TSL8HVUU9TTGW1_MMURIDIWRTTM",
@"use": @"sig",
@"kty": @"EC",
@"alg": @"ES256",
@"crv": @"P-256",
@"x": @"8dyzTlToUkMJ7tsl8HVuU9tTGw1_mmuridIWrttMRCs",
@"y": @"AVqGlqJ88QgP_uVLea7gIUnA-p9iYwnJyYt7o-uH4oU"
};
SecKeyRef publicKeyRef = restorePublicKey(jwk[@"x"], jwk[@"y"]);
NSString* header = @"eyJhbGciOiJFUzI1NiIsImtpZCI6IjhEWVpUTFRPVUtNSjdUU0w4SFZVVTlUVEdXMV9NTVVSSURJV1JUVE0iLCJ0eXAiOiJKV1QifQ";
NSString* payload = @"eyJub25jZSI6Indkd2R3ZHdkIiwiZGF0ZVRpbWUiOiIyMDIzLTEwLTEzVDEyOjQ4OjQwWiJ9";
NSString* signature = @"nWBfRne9VOKV4NGt32gWtoA5fUKzu0RzkhUYSYwUA7cvalsABUcWrpEk0fhztPZDK7KrDF8P2Pquhoxq4p-FUg";
NSString *headerAndPayload = [NSString stringWithFormat:@"%@.%@", header, payload];
NSData *signedData = [headerAndPayload dataUsingEncoding:NSUTF8StringEncoding];
NSString *signatureBase64Padd = base64StringWithPadding(signature);
NSData *signatureData = [[NSData alloc] initWithBase64EncodedString:signatureBase64Padd
options:kNilOptions];
bool canVerify = SecKeyIsAlgorithmSupported(publicKeyRef, kSecKeyOperationTypeVerify, kSecKeyAlgorithmECDSASignatureMessageX962SHA256);
if(canVerify) {
CFErrorRef error = NULL;
BOOL verifyStatus =
SecKeyVerifySignature(
publicKeyRef,
kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
(__bridge CFDataRef)signedData,
(__bridge CFDataRef)signatureData,
&error
);
if(error) {
NSError *err = CFBridgingRelease(error);
NSLog(@"%@", err.description);
}
} else {
NSLog(@"Cannot verify.");
}
}
return NSApplicationMain(argc, argv);
}
I dont know where is the problem. I've tried everything.
Hello,
I have read com.apple.security.app-sandbox entitlement is required for macOS applications distributed through appstore.
If so, how can it be possible for an application like Microsoft Word to read/write files in Documents folder ? It should be forbidden, due to sandbox ?
Thanks
Hi,
We're trying to generate the key inside secure enclave from the deamon, but it fails with the below error.
The operation couldn’t be completed. (OSStatus error -26276 - failed to generate asymmetric keypair)
Could you please help me to resolve the issue?
Hi, is it possible for a user to remove the implicit permission he or she gave to an app after opening a folder using a standard dialog? I'm asking this because a discussion took place with actual users reasonably arguing that the action may have been a mistake, not intentional at all, so at least we should give them a way to revert what was wrongly interpreted as intent. I believe that they are right and there should be a simple user-level way of doing that. So I looked for a way to remove the bookmark from the command line but to no avail. Thanks, Carlos.
Hi, Apple Developer team
I'm Security Engineer in my company.(We only work on mac at work.)
I'd like to get an RSS of the macOS release note site.
(https://developer.apple.com/documentation/macos-release-notes/macos-14-release-notes)
Can you provide the RSS url?
Thanks,
Kyle song.
I'm the developer of a Mac app that uses an authorization plugin to perform 2FA (password and approve in mobile app). There are four authorization use cases which we handle by updating the corresponding entries in the authorization database. The plugin is installed in the authorization database as follows:
system.login.console -> login
Replace: loginwindow:login
With: TrusonaAuthorizationPlugin:trusonaLogin
authenticate -> privilege escalation
Replace: builtin:authenticate
With: TrusonaAuthorizationPlugin:trusonaLogin
system.login.screensaver -> lock screen
Replace: use-login-window-ui
With: authenticate-session-owner-or-admin
system.login.fus -> fast user switching
Replace: loginwindow:login
With: TrusonaAuthorizationPlugin:trusonaLogin
Im macOS Sonoma 14.0 attempting to unlock the screen invokes the Privilege Escalation mechanism regardless of whether the "system.login.screensaver" record in the authorization database points to our authorization plugin or not.
When our authorization plugin is enabled for Lock Screen, clicking on the Lock Screen item in the Apple Menu invokes our authorization plugin for 2FA saying you need to authenticate to unlock the screen even though the desktop is not hidden.
Filed as FB13238136
Is there a way to disable TLS GREASE on NWProtocolTLS.Options.securityProtocolOptions.
Because it adds a 40 bytes overhead to the ClientHello. Combined with other factors (the padding extension),
this would cause the TLS handshake to take a significate amount of time on low bandwidth connections.
I tried using the private
funcion sec_protocol_options_set_tls_grease_enabled() but it did not work.
I'm using this code to get the path of an executable from the audit token provided in NEFilterDataProvider.handleNewFlow(_:), forwarded from the Network Extension to the main app via IPC:
private func securePathFromAuditToken(_ auditToken: Data) throws -> String {
let secFlags = SecCSFlags()
var secCode: SecCode?
var status = SecCodeCopyGuestWithAttributes(nil, [kSecGuestAttributeAudit: auditToken] as CFDictionary, secFlags, &secCode)
guard let secCode = secCode else {
throw NSError(domain: NSOSStatusErrorDomain, code: Int(status))
}
var secStaticCode: SecStaticCode?
status = SecCodeCopyStaticCode(secCode, secFlags, &secStaticCode)
guard let secStaticCode = secStaticCode else {
throw NSError(domain: NSOSStatusErrorDomain, code: Int(status))
}
var url: CFURL?
status = SecCodeCopyPath(secStaticCode, secFlags, &url)
guard let url = url as URL? else {
throw NSError(domain: NSOSStatusErrorDomain, code: Int(status))
}
return url.path
}
This code sometimes returns paths like /System/Library/PrivateFrameworks/HelpData.framework/Versions/A/Resources/helpd or /Library/Developer/CoreSimulator/Volumes/iOS_21A328/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.0.simruntime/Contents/Resources/RuntimeRoot/usr/libexec/mobileassetd.
But sometimes the SecCodeCopyGuestWithAttributes fails with status 100001 which is defined in MacErrors.h as kPOSIXErrorEPERM = 100001, /* Operation not permitted */. In these cases I resort to this code, which I have read is not as secure:
private func insecurePathFromAuditToken(_ auditToken: Data) throws -> String? {
if auditToken.count == MemoryLayout<audit_token_t>.size {
let pid = auditToken.withUnsafeBytes { buffer in
audit_token_to_pid(buffer.baseAddress!.assumingMemoryBound(to: audit_token_t.self).pointee)
}
let pathbuf = UnsafeMutablePointer<Int8>.allocate(capacity: Int(PROC_PIDPATHINFO_SIZE))
defer {
pathbuf.deallocate()
}
let ret = proc_pidpath(pid, pathbuf, UInt32(PROC_PIDPATHINFO_SIZE))
if ret <= 0 {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno))
}
return String(cString: pathbuf)
}
return nil
}
This insecure code then returns paths like /usr/libexec/trustd, /usr/libexec/rapportd, /usr/libexec/nsurlsessiond and /usr/libexec/timed.
From what I can see, SecCodeCopyGuestWithAttributes fails for all processes in /usr/libexec. Some of these processes have executables with the same name placed in another directory, like /Library/Developer/CoreSimulator/Volumes/iOS_21A328/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.0.simruntime/Contents/Resources/RuntimeRoot/usr/libexec/mobileassetd for which it succeeds, while for /usr/libexec/mobileassetd it fails.
Occasionally, both the secure and the insecure methods fail and in these cases the secure one returns status code 100003, which is defined as kPOSIXErrorESRCH = 100003, /* No such process */. When can this happen?
This seems to happen with both NEFilterFlow.sourceAppAuditToken and sourceProcessAuditToken. What is the problem?
I have created certificates to test development locally with HTTPS. You used to be able to drag-&-drop a certificate on the simulator, but this does not appear to work anymore. You can drag one onto the simulator and get the + drop symbol, but attempting to go into "VPN & device management" to trust it under General settings just shows a blank screen that bounces you out immediately.
Now what?
So nowadays my MacOS software uses an installer (http://s.sudre.free.fr/Software/Packages/about.html Packages) and it is able to correctly install the application.
My client needs to have a quiet installer because he needs to install the app in a large number of computers so using the interactive mode is not good.
I am trying to create a script to do that but I am facing the Read-only file system error. Of course my script runs as root. I tried creating a simple Swift code to check, I got the same.
So my question: why an installer such Packages can create the folder into the /System/Applications and copy the required files as it runs at the same level of the script and my test program and them don't have the same permission?
Since upgrading to Sonoma, I get two pop-ups saying that "NETserver" and "USBserver" would like to access data from other apps and asking for permission.
How do I get rid of seeing these pop-ups after every reboot? I have no apps specifically called "NETserver" or "USBserver".
Hi
I'm using library in my project which create, modify and read file in iConf. How to get access for the app to read from that file.
Tnx,
Filip
Hi Apple team,
Our app stores a private key in keychain services (kSecClassGenericPassword) via expo-secure-store. We need urgent help in recovering an item stored in the keychain AFTER an iCloud Restore has happened.
The private key is specifically stored with the kSecAttrAccessible trait of kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly.
STEPS TO REPRODUCE (iPhone 14 Pro, iOS 16.7)
Write an item to the keychain via expo-secure-store using the described attributes (on an app that's dispatched via Testflight)
await SecureStore.setItemAsync("private_key", private_key, {
requireAuthentication: true,
authenticationPrompt: "Unlock your private key",
keychainAccessible: SecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY,
}),
Create an iCloud Backup for the device.
Factory Reset the iPhone (Erase all content, apps, and settings)
Restore the iOS backup from earlier and then attempt to retrieve the keychain item.
Is there any way at all of retrieving this keychain item after an iCloud backup has been restored?
Note. Our app has only been deployed via Testflight and there is no store listing. After restoring the device from an iCloud backup, our app icon has a small "download"/cloud icon beside it. When tapped, we get an error saying "Unable to install " because the app is not listed in the App Store.
Is it possible that being on TestFlight is causing the keychain items to be wiped?
I have items written to the keychain by an XPC service. On disk, it's just a plain binary.
There are times when this service shows a system authentication dialog via LAContext. By default, the application icon is a tiny version of a terminal. We found that if we wrap the binary in a bundle, we can include an icon and it will show up in the authentication dialog.
The problem is that this new bundle seems to be different, as updates to an existing keychain item (created by the old, standalone binary) fail with errSecInvalidOwnerEdit. The bundle ID of the embedded binary has not changed.
How does the system decide who is the owner of a keychain item and is there any way to do a migration like this without affecting item ownership?
I need to store some data of my application in system keychain which should to accessible to all the users in the system.
Here is the below sample code :
// Create a SecAccessControlRef for a keychain item with access control
SecAccessControlRef accessControl = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlocked,
kSecAccessControlUserPresence,
NULL
);
// Define a query dictionary for a keychain item
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: @"MyService",
(__bridge id)kSecAttrAccount: @"MyAccount",
(__bridge id)kSecValueData: [@"MyPassword" dataUsingEncoding:NSUTF8StringEncoding],
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)accessControl,
};
// Add the keychain item to the default keychain (login keychain)
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
if (status != errSecSuccess) {
NSLog(@"Error adding keychain item: %d", (int)status);
}
I tried using SecKeychainOpen to access the system keychain but SecKeychainOpen is deprecated and I could not find any equivalent latest API to support that.
SecKeychainRef systemKeychain;
OSStatus status = SecKeychainOpen("/Library/Keychains/System.keychain", &systemKeychain);
if (status != errSecSuccess) {
NSLog(@"Error opening system keychain: %d", status);
} else {
SecAccessControlRef accessControl = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlocked,
kSecAccessControlUserPresence,
NULL
);
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: @"MyService",
(__bridge id)kSecAttrAccount: @"MyAccount",
(__bridge id)kSecValueData: [@"MyPassword" dataUsingEncoding:NSUTF8StringEncoding],
(__bridge id)kSecUseKeychain: (__bridge id)systemKeychain,
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)accessControl,
};
// Add the keychain item to the system keychain
status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
if (status != errSecSuccess) {
NSLog(@"Error adding keychain item to system keychain: %d", (int)status);
}
if (systemKeychain) {
CFRelease(systemKeychain);
}
}
ANY suggestions will be helpful, Please help!
I am trying to establish a TLS 1.3 connection to a server that only accepts the SECP256R1 and FFDHE2048 TLS key share groups using the following code but the server is failing the TLS handshake because my client is not using a supported key exchange group. How do I specify which TLS key exchange group my client should use during the handshake?
let tlsOptions = NWProtocolTLS.Options()
if let secIdentity = getSecIdentity(),
let identity = sec_identity_create(secIdentity) {
sec_protocol_options_set_min_tls_protocol_version(
tlsOptions.securityProtocolOptions, .TLSv13)
sec_protocol_options_set_local_identity(
tlsOptions.securityProtocolOptions, identity)
}
let tlsParams = NWParameters(tls: tlsOptions, tcp: .init())
let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(host), port: NWEndpoint.Port(port))
let nwConnection = NWConnection(to: endpoint, using: tlsParams)
nwConnection.stateUpdateHandler = stateDidChange(to:)
nwConnection.start(queue: queue)
Thanks!
Basically what it says in the title.
Is it expected that /var/db/auth.db is recreated when updating to a newer macOS major version?
This effectively removes the installed authorization plug-ins from the login flow, decreasing the intended security. And it's not a good end-user experience either to have to reinstall the plugin after updating - nothing such can be noticed with regular applications.