OS X sandboxing questions - macos

I have a Mac application in the App Store and am looking to adopt sandboxing before it becomes a mandatory requirement. I've run into two issues and was hoping to post here for some insight into best practice in the following situations:
Within my application I use an NSOpenPanel to prompt the user to load a proprietary file format. After loading the file my application parses it and gathers a list of NSURLs to local files. These local files are then passed to NSImage's initWithContentsOfURL: method. Unfortunately, the act of loading the image files causes the sandbox to cancel the action. I understand that this happens because the user has given my application explicit permission to open the file selected by the NSOpenPanel, but not for the files referenced within my proprietary format. How can I handle this (supposedly fairly common) situation?
I have a unix executable file contained within my applications bundle that I would like to execute using an NSTask. Is this legal under sandboxing, given that the script is contained within my bundle?
If anyone could clarify the above points, that would be appreciated.

1) From my understanding the NSURL object contains the permissions necessary to re-access the files later, so if you are using hardcoded paths, you could replace them with archived NSURL objects. This is also assuming the user selected those filies within an NSOpenPanel at an earlier point.
2) You can run a NSTask but it inherits the permissions of your main app.
Hopefully others can chime in with more information. I've found the Mac Developer Boards, specifically the "Application Sandboxing" forums to be helpful, as Apple employees often drop in. So far, I've found sandboxing to be an unusable mess.

Easy one first: you can run your helper with NSTask and it will inherit the sandbox of your app.
Those URLs: not easily/reliably/at all. There is a way to save NSURLs to files you have access to in such a way that a subsequent run of your application and re-load them and regain access, however it is deemed fragile and not to be recommended. Read the Apple developer forums and this is an Apple acknowledged problem they are "working on"; given this using the fragile solution is probably not worth the effort - search the developer forums for the fragile solution if you really want to hack something that sort of works now.

Related

Can i create a mac application using xcode that runs scripts?

I am very new to making applications, and using Xcode, so I don't know much about it... I'm using Xcode 5.0.2 to attempt to create a basic osx application which will allow the user to search through a list of built in scripts, select the ones they would like to run, and push a button to run the scripts. I have several scripts already, all of which have the extension .scpt. i wrote the scripts using applescript editor.
From searching this website, and the rest of the internet, i haven't found a clear, step by step answer of what to do. I know that in order to run the shell script, there must be an interface button linked to an action in the implementation file, which is what will execute the script.
What is the action i have to put in the implementation file?
How do i link the button to the action?
where do i put my .scpt files?
I have absolutely no code written in Xcode, it is nothing but a blank new project.
I don't have much experience with Cocoa apps, if you have experience with Visual Studio this is nothing like it, I started by looking some videos from the link below, they're really helpful, he also provide a full course for Objective-C.
http://www.youtube.com/playlist?list=PLE83F832121568D36
I hope this helps!
There is a huge amount of aspects to the problem you are trying to solve. Honestly, connecting the NSButton to an Action is just taking the first (small) step! Just a few of the aspects you may encounter:
How are the files executed? (your main question)
How is the selection interface set up?
How to read from the files? How to process the data you read?
What kind of actions will your scripts perform? What is in fact allowed from within a Cocoa app? (I have no idea myself to be honest)
Each one of these suggests potential SO questions in itself.
I would suggest that you familiarise yourself with the environment and the language a bit before taking big leaps. Take some time (a few days at least) and follow some tutorials, program some simple apps. The link provided in the other answer is in fact a good one, AppleProgramming tutorials are easy to follow. You may also find Apple's Objective-C intro useful.

How can I show my app is not a keylogger?

I've created a simple Mac app that gives you statistics on your working behavior over time. For example, your average words per minute, what language you are typing in, usage of the delete key, etc. Interesting stuff! However, some test users have said they wouldn't use the app if they didn't know me personally, since it collects keystrokes like a keylogger.
Is there some certification I can get to show that I'm not doing anything nefarious? (I never keep more than one word in memory!) Or will it be enough to have my app signed? Or open-source that part of the code? (Other parts I know I cannot make open source.)
Distributing through the Mac App Store will help, since users can see that Apple has tried your application and found nothing nefarious in it. [Added:] Also, sandboxing your app means that your app is restricted to an explicit set of abilities, which technically-skilled users could inspect. Anything not listed, you're unable to do, so this would be an easy way to prove that you don't send anything back over the internet.
Another thing would be to save all data in user-readable files. No binary plists, no Core Data stores, etc. (Whether the XML variants of either of those should count as user-readable would be more arguable, but for this purpose, I think at least an XML plist would be readable enough. Not sure about Core Data.)
If the user can read all of the raw data you store using applications that they trust (such as TextEdit), and not just your usual fancy in-app presentation of it, then they can check for themselves, and eventually trust, that you're not storing anything they wouldn't want you to.
If any concerned potential users email you about whether you report their keystrokes to your own server via the internet, and assuming that you don't make any internet connections at all (not even an update check), you can recommend that they should install Little Snitch, which pops up a confirmation alert anytime any app tries to connect to something. When they don't see such an alert about your app, they know that you're not phoning home.
You might also, on your product webpage, include a link to a tech profile. Here's Jesper's article proposing them, and here's one example of such a document, for one of his products.
I would think that Gatekeeper would be adequate for most users. If it turns out an app is doing bad things, then Apple could pull the plug on a malware developer. So that and maybe some time live should establish your program as 'safe' to those who are not technically inclined (e.g. cannot understand your source).
Simply distributing it in your or your company's name can do a lot to build trust in an app (provided of course your other products/programs have not violated users' trust).
If you can get the application onto Apple's App Store, then that means they will have checked it for such problems. There's no way they'd knowingly allow a key-logging app on there. Also, signing the app with an Apple certificate ensures that if it has been downloaded from the App Store and later is found to be nefarious, they can black list it.
Open-sourcing code would also be a good idea. I assume you can't Open Source all of it because it doesn't belong to you? If so, then make it clear what technologies it uses and be as open and honest about what the application does and how it goes about doing it.

Modification of signed applications

I'm trying to get a better understanding of OSX Code Signing and the advantages that it affords me in terms of protecting my software. Could someone please clarify certain questions for me?
Given an application that is Code Signed but not sandboxed:
Should a hacker change the application's binary the application is no longer considered as signed. However will it still run correctly (with the Caveat that Lion will warn the user about the application not being code signed)?
Given an application that is Code Signed and sandboxed:
What will not happen if a hacker changes the code in this case? Can he/she simply remove the entitlements file to create an unsigned version of the application that no longer has any sandbox restrictions?
Given a signed but not sandboxed application that contains a signed and sandboxed XPC service helper is there anything I can do to guarantee that a hacker can't create a non-signed (and modified) version of either part. It seems to me that as it currently stands a hacker can do the following:
Create a binary-modified version of the helper. This new version
would thus be non-sandboxed and non-signed.
Create a binary-modified version of the main application. This new
version would thus also be non-sandboxed and non-signed, and able to
start up the new version of the helper.
Am I wrong? If so, why?
Thanks,
Tim
You're basically right. What you're looking for is copy protection, and that's something nobody's ever figured out how to do (well), and it's not something that either code signing or sandboxing attempt to do. What sandboxing does is limit the damage if your program is taken over at runtime and made to do things it's not supposed to. What code signing does is prevent someone else from passing their program off as yours.
I used the words "their program" intentionally. You have to realize that once "your program" is on someone else's computer and they start messing with it, it's not really yours anymore; it's theirs, and they can do pretty much anything they want with it. They can take parts out (sandboxing, etc) add parts (malicious code, etc), change things, ... They could even write a "completely new" program that just happens to include parts (or the entirety of) your program.
There are things you can do to make your code hard to modify/reuse, but nobody's ever figured out how to make it impossible. Apple isn't trying; their security measures are aimed at other targets.

Is a launchd daemon the best route to go for reading/writing to privileged files in Cocoa?

I have an application which needs to be able to write to Any User/Current host preference files (which requires admin privileges per Preferences Utilities Reference) and also to enable/disable a launchd agent via its plist (writable only by root).
I'm using SFAuthorizationView to require users to authenticate as an admin before altering these values.
I'm trying to decide on the best way to do the actual altering of these values.
The cheap hackish option seems to be to use AuthorizationExecuteWithPrivileges() and mv or defaults, either via BLAuthentication or creating something similar myself. The downside to this is not getting the return value of whatever command line app I'm executing, plus some odd esoteric bugs I've encountered (such as getting a -60008 error in certain situations). This is strongly recommended against by Apple, obviously, but people do seem to do it and have some success with it.
The second most hackish option would seem to be the whole create a helper app with the suid bit set and the --self-repair option as discussed in various places. This seems possible, but like it's probably not much less trouble than the third option.
The third option is to create a fully fledged launchd daemon which will run as root and communicate with my application via a socket. This seems like a bit of overkill to read and write some plist files, but it's also possible I may find other uses for it down the road, and it wont be the only daemon for my application, so it doesn't seem unreasonable to just add another.
I'm thinking about modifying this sample code for my purposes.
My two questions are:
Does the launchd daemon option seem like the best route to go for this, or is there a much easier route I'm missing?
Has anybody else successfully used that code as a basis for something similar, and does anybody see any glaring issues with it I'm missing? I've used it successfully in a test app, but I'd be curious to hear you guys' opinion on it.
launchd is definitely the best and safest way to go: you’ll need an installer package to get your helper into place. Do be sure that your helper does and can do absolutely nothing except edit the files you wish to target.
No experience w/the code, but it’s based off of BetterAuthorizationSample, so that’s a nice start.
There's also the openauth API, which allows you to open files that require root privileges.

File-level filesystem change notification in Mac OS X

I want my code to be notified when any file under (either directly or indirectly) a given directory is modified. By "modified", I mean I want my code to be notified whenever a file's contents are altered, it's renamed, or it's deleted; or if a new file is added. For my application, there can be thousands of files.
I looked as FSEvents, but its Technology Overview says, in part:
The important point to take away is that the granularity of notifications is at a directory level. It tells you only that something in the directory has changed, but does not tell you what changed.
It also says:
The file system events API is also not designed for finding out when a particular file changes. For such purposes, the kqueues mechanism is more appropriate.
However, in order to use kqueue on a given file, one has to open the file to obtain a file descriptor. It's impractical to manage thousands of file descriptors (and would probably exceed the maximum allowable number of open file descriptors anyway).
Curiously, under Windows, I can use the ReadDirectoryChangesW() function and it does precisely what I want.
So how can one do what I want under Mac OS X? Or, asked another way: how would one go about writing the equivalent of ReadDirectoryChangesW() for Mac OS X in user-space (and do so very efficiently)?
EDIT: Not verified, but Konstantin indicates below that this code sample is obsolete as of 2012.
I don't believe there's a specific API for what you're looking for. Apple provides sample code for a similar problem called Watcher. It is not what you are looking for, but it is about the best you can do at this point. You have to take snapshots of the directory, and rescan it when you find out something changed. Modification time is the best thing to check of course, if you can trust modification time.
You are probably correct that trying to register for an unbounded number of kqueues would likely be unworkable.
I haven't tried this myself, but it seems like FSEvents is able to provide file-level notifications as of 10.7 (Lion). From the description of FSEventStreamCreateFlags:
kFSEventStreamCreateFlagFileEvents
Request file-level notifications. Your stream will receive events about individual files in the hierarchy you're watching instead of only receiving directory level notifications. Use this flag with care as it will generate significantly more events than without it.
Available in OS X v10.7 and later.
The closest utility (that I know of) that matches your needs on Mac OS X is fslogger.
See the link for a description, dmg and source code:
OSXBook - fslogger
You might want to check out man fs_usage, though it's not specific to a directory and requires root privileges.

Resources