WWDC2013 Session 710

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
>> Speaker 1: Hi.
How's it going?
Welcome to the most
magical session at WWDC.
I think of this session as the
centerpiece of the conference
and then we announce
some other stuff too.
But, we're going to be talking
about App Sandbox today.
And, before we really
get into that,
we're going to talk about cars.
A lot of us drive, a
lot of us know, sort of,
how cars have been evolving
as time has gone on.
And I found, I found it pretty
interesting that just a couple
of years ago traffic
related fatalities
in the United States have
actually reached a 50 year low.
The NHDSA has statistics on this
and the numbers have been
getting better and better
and they're, basically, at a
really long low at this point.
And if you look at why that is,
it's because the car
industry has been investing
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
into safety mechanisms
for a long time.
It's because you
can't sell a car
without passing Federal
Safety Certification.
But, what's more interesting
to me, is how that investment
into safety has actually
worked out in practice.
On the one hand, there's been a
tremendous amount of innovation
in trying to prevent
accidents from happening.
So, just in the last year or
two, you're seeing a bunch
of new mechanisms in modern
cars where, for instance,
there is blind spot detection.
The car will actually beep
at you if you're trying
to change lanes and there's
a car in your blind spot.
There are really a number of new
electronic mechanisms that are,
for instance, how can
you, if you're trying,
if you're drifting
out in the lane,
sensors can now notice
and warn you.
A lot of things that are trying
to help drivers be more
alert even on longer trips
and make sure that you
never get in a position
where you're in an accident.
And all of those have
been really helpful.
Almost orthogonal to all of
those, there's been a number
of mechanisms that try to
make it so that if you wind
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
up in an accident,
harm is minimized.
Seatbelts and airbags are
the prime examples of this.
For many of you, I'm sure,
this is just something
that's always been a part
of the car but, actually,
seatbelts were not
standard equipment until,
I think, the '60s.
Airbags were not
standard equipment
in most U.S. cars
until the '90s.
And those standards are
evolving even today.
So, it's interesting to
me because, obviously,
the best case scenario is you
never wind up in an accident.
But, if you do, the car is
trying to be prepared for it
and is trying to keep
you from getting harmed.
So, if you have that
model in mind and you look
at how computer security
used to work on desktops
and desktop operating systems,
it's really been
very, very different.
There has never been a
seatbelt or an airbag
for a desktop computer.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
In other words, it was
all about making sure
that an attack never succeeds.
But, once it does,
there was really no way
to contain the damage,
to contain the impact
of a malicious piece of software
that has successfully
exploited the vulnerability.
It has just been defenders
trying to defend 100 percent
of the attack surface
all the time,
the attacker's finding 1
hole, 1 time and winning.
So, why is that?
It turns out that the way
we got here, as an industry,
is because of assumptions
that were made in the era
of the original UNIX
being designed
with Ritchie and Thompson.
Where they made this
underlying assumption,
that I now call the
unfortunate assumption,
which is that every program
runs with the full privileges
of the user that
ran that program.
In other words, we should
direct security barriers
between different users
of the same system,
but not between different
apps from the same user.
And, again, if you sort
of look back and think
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about why 40 years ago
this assumption was made,
it was because it
made total sense.
There was no such thing as
untrusted code being run
because all the code
that would run was code
that you manually
put on a punch card,
walked up to a machine,
loaded and ran.
So it was pretty reasonable to
say that that code should run
with your full privileges
and that
that wouldn't be an
issue in practice.
But, today, most machines
are single user machines.
We run untrusted
code all the time.
Every time you visit a website,
that's what's happening
under the covers.
And so it's sort of clear
that apps should be only
accessing the information they
actually need to
get their work done
and not having unrestricted
access to your whole computer.
I have an example
that I, that I like.
This is a beautiful
new application updated
for Mavericks.
It's called Watch Grass Grow.
I spent a lot of time with
this app and it's gorgeous.
It shows grass growing in
real time and, you know,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
it connects to the network
every once in a while
to pick up new grass assets.
So, for instance, droplets
on shimmering blades of grass
that come over the network.
Beautiful stuff, but this
app should never be able
to access any of my data.
If somehow, in the process of
making these network requests,
this app were to
become exploited,
it could normally
access all of my data.
It could read my E-mail,
it could change my computer
settings, it could look
at my browsing history.
All stuff that it should
never be able to do.
And the way that the computing
industry has traditionally dealt
with this is by erecting
user interfaces that try
and get users to make
the right decision
which is what this normally
looks like to a normal user.
In other words, security
interfaces generally don't work.
They're expecting way too
much background understanding
of how computers work from
normal users who don't have
that kind of knowledge.
And, as a result, over the years
users have actually basically
been conditioned to just
look for the Allow button.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And press it because it
maximizes the chances
that they can get done the thing
they were trying to get done.
Obviously, rendering
the whole point
of the user interface moot.
There's this great saying
in Washington, D.C.,
it's a political
saying which says,
if you're explaining you're
losing, and I think it applies
to security interfaces as well.
If you're hoping that a user
understands the details of X.509
and SSL certificates and can
make a valid decision about what
to do, you're probably losing.
So, that is how things
used to be and, obviously,
the landscape has really changed
a lot in the last few years.
Tons of apps and
tons of developers,
it's never been this
easy to be a developer
or to write apps
largely facilitated
by the App Store revolution.
And, while that's happened,
computers have also
basically started
to be always on networks.
Ubiquitous Wi-Fi and, for
mobile devices, radios,
our computers spend much,
much more time connected
than they do disconnected which
didn't use to be the case.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Finding new software, super
easy; it's never been this easy.
And so it really underscores
that today's challenge
for security is to isolate data
between different programs,
not between different users.
So, when I normally try and
pitch people on, you know,
how some of this
background works,
I get a lot of different
responses.
And one frequent one
is developers saying,
well I have a really simple
app, it doesn't do much.
And I am very careful,
I understand security
and I'm pretty sure that my
code doesn't actually have
vulnerabilities so why do I
have to bother with any of this?
And the answer is because even
though your app may be simple
and pretty constrained
in what it does,
remember that you're linking
against millions and millions
and millions of lines of system
libraries and other libraries
and frameworks which are doing
incredibly complex things behind
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
the scenes where you might
not have even thought of them.
So, you know, you might
have a super simple app
that just shows a web view
to authenticate the user.
That web view, in
terms of complexity,
is practically a small
operating system, right?
It's millions of lines
of code to render HTML,
to run a just-in-time
JavaScript compiler,
it's a huge amount
of complexity.
And a single vulnerability
anywhere in all the code
that your app has plus all
the code it links against used
to mean a really bad
day for the user.
Attack finds one
hole, attack wins.
There's no containment
of damage, that's it.
So it's against this
backdrop that, in Lion,
we introduced App Sandbox,
a mechanism that tried
to make it much easier to write
secure applications for OS X.
And it tried to do this by
doing something really different
which is, instead of trying
to drive security policy
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by explicit user
choices through prompts,
it tried to drive security
policy through user intent.
And it tried to, in effect,
do this so that it can then
contain damage from exploitation
or even a misbehaving app such
as pathological bugs in the code
that would try to delete
or corrupt user data.
So, how does this work?
Well, the premise is this.
You write your apps which means
you know what your apps are
meant to be able to do when
they're working properly.
We take that app in
the operating system,
we assign it its own
space on the file system
that we call a container,
and then the operating system
lets the user control what other
data your app can get access to.
And it does this by making all
the special cases like drag
and drop and recent items
and so forth just work
magically under the covers.
So, let's talk about
the key components here.
I mentioned that you specify
what your app is meant
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to be able to do.
And the way it does this is by
using what we call entitlements.
Entitlements are
actually very simple,
they're just a very
simple plist.
You can-- Xcode gives you a
beautiful interface for it
and I'll show you that in a bit,
but it is just a
very simple plist.
And the idea behind entitlements
is that they express concepts
of access that should be
easily understandable even
to an end user even
though it's not ever meant
to be seen by an end user.
So here are some examples of
things that are entitlements.
Entitlements are things
like I want to be able
to access a Downloads folder,
I want to be able to talk
to the network, I
want to be able
to access the user's
Address Book.
Now I mentioned that we
take your app and we put it
in a container and the way this
works is there's actually no
deep magic happening.
When we're launching your app,
we set 2 environment
variables called Home
and CFFIXED-USER-HOME
and we point them
at a file system location
that we assign specifically
for your app.
And we basically pretend
that that location is the
user's Home Directory.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, here's what that looks
like where we have an app,
we just put in a Sandbox
and, if in the app,
we have a direct
open system call
with the specific path inside
their real Home Directory
of the user, the Sandbox
denies this access.
And says, actually no, that's in
the user's real Home Directory,
this aisle doesn't yet
have access to that.
But if the app, instead, calls
Apple API like NSHomeDirectory,
well the answer that it'll
actually get is its own
container location which means
that it's within the Sandbox
which means access is allowed.
So then, you might say, well
okay, but an app is not going
to be very useful if all it can
access are files that it read,
then wrote in its
own little space.
How does it actually get access
to the real files
that the user has?
And the answer is the Powerbox.
The Powerbox is a trusted
operating system facility
in OS X that makes it
so that Cocoa NSOpen
and NSSave panels are
actually drawn out of process
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by a trusted system service.
And, if you think about
open and save panels,
they're this really unambiguous
declaration of user intent.
If you have an app open
and there's an open panel
and the user select
a file or folder,
it's really clear what
the user's trying to do.
They're saying I want to open
this file or folder in this app.
So by moving the
open and save panels
to be a trusted system service,
we can take that declaration
of user intent and then
form security policy
around it specifically
by making those files
and folders then
available to the app.
Let me show you what
this looks like.
Here's an app, it links
against AppKit in the top
and we're going to
put it in the Sandbox.
And let's say that the
app wants access to a file
within tilde documents.
Well an NSOpen panel is
presented and normally,
because this app is
Sandboxed, if AppKit were to try
and get access to tilde
Documents directly,
this would just fail.
The sandbox would say,
no you're not allowed.
But what happens in
the App Sandbox world,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
because of the Powerbox, is that
AppKit realizes it's running
in a Sandbox and so, instead
of presenting the
open panel directly,
it calls out the Powerbox
and says, Powerbox,
please present an open
panel on my behalf.
Powerbox also links against
AppKit, but it's not Sandboxed
so it has access to documents
which means it can draw the
open panel on the app's behalf.
This looks exactly like
it's always looked.
You never know that
you're using the Powerbox,
it's just completely
under the covers.
But, once a user selects a file
or folder in this open panel,
that file or folder is then
made available directly
in the Sandbox of your app.
Finally, XPC Services
are the easiest mechanism
that there's ever existed to
split up parts of your app
into separate functional units
that can have different security
policies assigned to them.
Why does this matter?
Well because, as apps get
more and more complex,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
they do more and more things.
And if, in the end, you have a
single monolithic app that has
to be able to access all
kinds of things from hardware
to private information
to user documents.
Then, even though the app
Sandbox still provides some
mitigation if that app
were to become exploited,
it may be that an
attack on that app
that succeeds can already get
access to so much information
that maybe that's all
the attacker cares about.
So to try and mitigate this,
you can break out pieces
of your code, especially, highly
sensitive pieces of your code,
for instance, the deal with
the network into XPC services
that are made available
to your app.
And then you can, basically,
Sandbox those independently
and restrict their
access to things
like sensitive user information.
And with XPC, the service's
lifetime is fully managed
by the operating system
so you don't have to worry
about starting them
up and tearing them
down when you need to.
You don't have to
worry about, you know,
whether they're running
when you want them.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It's just done for
you by the OS.
So that's a lot of concepts.
What does this actually
look like?
I'm going to show you this
on TextEdit because it's--
you can look at that source code
and TextEdit has been Sandboxed
since Lion, but we're going to
pretend it's not and we're going
to show you what it
looks like to Sandbox it.
And the process we're going
to follow here is we're going
to look at the Entitlements
list and kind
of pick the ones
we think make sense
for a program like TextEdit.
We're going to code sign
TextEdit when building it
which will cause the
Entitlements to take effect.
We'll double check that
TextEdit, as it runs,
is in fact Sandboxed
like we expect.
And then, finally, we'll
look for Sandbox violations
that the OS is reporting
to try and figure
out if we're maybe missing
some Entitlements that we need.
And I should note that
for the last two WWDCs,
the app I've used as
my demo app is Adium
which is a really popular
instant messaging client.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And I'm thrilled to be
switching to TextEdit this year
because the actual Adium
app became Sandboxed.
The developers took
it, Sandboxed it,
and so if you download Adium
now, it is Sandboxed so I feel
like I needed a new example.
Okay. So here's the
TextEdit project.
And what we'll do is
just run it, here it is.
And what I've done is I've
grabbed activity monitor here
and I've filtered it by TextEdit
so you can see the
process right there.
And in the View menu in columns,
I've actually enabled
the Sandbox column
so that you can see that
right now TextEdit is
running unsandboxed.
So let's see if we
can Sandbox it.
We're going to click
on the target and,
in the Capabilities
tab in Xcode 5,
it's really this very
nice graphical editor
of various capabilities, App
Sandbox is just one set of them.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, we'll flip on the
App Sandbox switch
and TextEdit obviously needs
to be able to edit files
that a user selects
so that seems
like an obvious Entitlement to
give it if it wants to be able
to both read them and write to
them so we'll say read/write
to user selected files.
That seems about right.
Let's run it now.
There's TextEdit and in Activity
Monitor, you'll notice now
that the Sandbox
column indicates yes.
So this thing is
running Sandbox.
So that's it, is there
anything more to it?
Well, we want to check if there
were any errors encountered
while TextEdit actually ran in
the Sandbox so we'll switch here
to Console where I'm filtering
by output of the Sandbox daemon.
And, indeed, you'll notice
that there's actually a bunch
of messages indicating
that SandboxD is telling us
that TextEdit was denied certain
operations by the Sandbox.
So it looks like it was denied
the ability to do a mach lookup
on SCNetworkReachability and
some system socket access
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and then some more mach
lookups to com.apple.networkd.
So why is that?
Well, it's because this
particular TextEdit tries
to make a network
connection when it starts
and I didn't enable
that in my Entitlements.
All I need for TextEdit
to be able access the
network here is allow it
to make outbound
connections to the network
to act as a network client.
So why don't we enable that?
And rerun TextEdit.
There it is.
And you'll notice there were no
more violations shown meaning
TextEdit is running Sandboxed,
everything's operating
like we want, no violations
are getting logged, that's it.
TextEdit is Sandboxed.
What did we really
accomplish there?
Why did we do this?
We did it because, even though
that took us all of 3 minutes
to do, the TextEdit before we
Sandboxed it and the TextEdit
after we Sandboxed it
behave very differently
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
if you can exploit them.
Right now, when it's
Sandboxed, if you are able
to somehow attack TextEdit and
exploit it, all you get access
to as an attacker are the files
that the user currently
has open in TextEdit.
Nothing else, no other
access to the user's disk.
No other access to
the user's hardware.
No access to user's E-mail,
no access to user's browsing
history, you're contained.
You can't install applications,
you can't change the
TextEdit application
to put a Trojan in there.
You're pretty tightly contained.
And, in order to really launch
a successful attack here,
you need to chain
multiple vulnerabilities,
some of them probably
kernel vulnerabilities
to really pull off
a strong attack.
So that's a tremendous
improvement in the safety
of TextEdit as an app.
And if that resolved it
for very many of you,
that is about all the exposure
to App Sandbox that you'll need.
You'll be able to go in and look
at the Capabilities interface
in Xcode 5, tick
some boxes, try it,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
check for violations,
and you'll be done.
But, as your apps
get more complex,
you may also need some
advanced functionality and I'd
like to show you what
else we have on offer.
The first thing I'm
going to talk
about is a mechanism called
Security Scoped Bookmarks.
And, to understand
where this comes from,
I have to tell you a bit about
how files and access given
to files are managed
as your app runs.
So your app starts, it has
access to nothing outside
of its container, the user
then gives it access to a file
or folder through the Powerbox.
And so now, while
the app is running,
it has access to this new file.
But, as soon as your app
quits, it loses that access.
The next time it starts, it no
longer has access to the file
that the user opened last time.
And this is the only reasonable
default because, otherwise,
the amount of things that apps
can access would just grow
without bound, over time,
as the apps are used.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So defaulting to losing the
access as the app restarts,
is the right thing to do.
But it's not, it can't
be the only option.
There are apps that really
legitimately need to be able
to preserve access
to files and folders
that a user selected
across launch.
And, usually, those use
cases fall into 2 categories.
There are what we call
app-scoped bookmarks
where the preservation of access
to files and folders comes
as part of the app's
configuration.
And then there are
document-scoped bookmarks
which pertain to
document formats
where the document itself can
actually reference files all
over the disk and you
want to be able to have
that continue working as
the document is opened
and closed potentially
across different apps.
So, for app-scoped bookmarks,
there is no special Entitlement,
it's actually provided-- the
ability to use this is provided
if you simply have the user
selected files bookmark.
And what I have here
is an example
from the Mail app where--
which is Sandboxed by the way.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can see that you
can select the folder
to which attachments will
get downloaded automatically.
And so, if you think about it,
if the user chooses a different
folder here and mail loses
that access on re-launch,
that wouldn't be very helpful.
So, somehow, it needs
to be able to say,
I'm going to preserve
the user selection
and always have access to it.
So app-scoped bookmarks
allow you to do this
and they lock the files or
folders that the user selected
to your specific app running
as that specific user.
So here's what that looks like.
The user is going to
pick a file or folder
and make access available to
your app such as your Powerbox.
Your app is going to turn around
and take that file and pass it
on to the
bookmarkDataWithOptions API.
This is the same API that's been
around for years now, actually,
just for normal bookmarks.
And this API is going to produce
just an NSData, an opaque blob
that represents the app-scoped
bookmark which your app is free
to store anywhere it pleases
such as in its container
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
as a file or in user
defaults or even in Core Data.
It doesn't matter
so long as it's
in a place that's
accessible to the app later.
Then, on next launch, when the
app needs access to this file
or folder, it'll simply
fish out that NSData
from wherever it stored it,
pass it into the
URLByResolvingBookmarkData API
which will check that the
blob came from the right app
and the API provides access
to the file or folder.
If some other app were
somehow to get a hold
of that same app-scoped
bookmark,
this simply wouldn't work,
the API would say, no,
you did not create this
bookmark, you cannot resolve it.
The other use case,
the document-scoped
bookmark use case is useful
if you have a document format
that needs to be able to link
to movies or pictures
or other large files
that may be all over the disk.
And the restrictions
differ for document-scoped
and app-scoped bookmarks.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
For document-scope, they
are openable by other apps,
but the target of the
bookmark cannot be
in a certain restricted
set of locations.
So you can't bookmark Contents
and things like tilde Library.
And currently you
can't document,
you can't bookmark folders,
it must be individual files.
So here's what the
document-scoped case looks like.
The user is going to create
the document in your app
and they're going to link
a movie into that document
so you're going to turn around
and actually pass both of these
into the bookmarkDataWithOptions
API and say, I am planning
to take this movie that
the user gave me access to
and I'm planning to insert
it into this document.
And the API produces
another NSData blob
that basically must be inserted
in the document you said you
were going to put it into.
So that's what your app does.
Then, when the user
reopens the document
which now has this link that,
currently, from your Sandbox,
you can't follow to the movie.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can take that security
scoped bookmark out of
that document and say, I
retrieved it from this document
and here's the bookmark.
Pass both of those to the API,
the API will resolve the
bookmark, provide you access
to the movie and now you
can recreate this link
and follow the reference.
I should mention that, for
document-scoped bookmarks,
if you think about it, document
formats need to generally run
between different apps.
So if another app can
open the same document,
it can actually resolve
that very same bookmark.
So, as I mentioned,
there's no new API
to the security scoped
bookmarks,
it's the same bookmark
API that has been
around for several years.
In case any of you are not
familiar with bookmark API,
it's actually the modern
replacement to things
like aliases and
FSRefs so, basically,
an API for being able to, as
best as the OS can, track files
and folders as they move around
the file system or get renamed.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But there's one critical
difference
between the normal bookmark
resolution API and using
that same API for
security scoped bookmarks.
And that is that when you
resolve a security scope
bookmark, what you get back
is what we call a security
scoped NSURL.
It's an NSURL, it tells
you where the file is,
but you can't immediately
go and follow it.
It has not yet been made
available inside your Sandbox.
Instead, you are responsible
for calling a method
on that URL object
called startAccessing
SecurityScopedResource.
And it's the act of calling
that method that makes the file
or folder available
within your Sandbox.
When you're done with
the file or folder,
you have to match the call
with stopAccessing
SecurityScopedResource
which tells the operating
system to free up resources
that it's using on tracking
which additional files are
available inside your Sandbox.
This is really important because
if you don't call StopAccessing
and you start accumulating many,
many, many Sandbox extensions
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that were done in this way,
eventually your app will,
basically, not be able
to take in anymore.
And opening files through the
Powerbox will start failing.
It's not a good place
to be, basically,
until your app is restarted.
So balancing these
is very important.
One other thing that App Sandbox
focuses on is making sure that,
by default, applications
really can't talk
to each other directly.
Generally, communication between
Sandbox apps has to happen
through some kind of
operating system interface
and mediation which, again,
turns out to be the
right default.
But there are totally
legitimate use cases
where multiple applications
want to be able
to establish direct
communication channels
or just share files
and folders on disk.
The most common case for this
is suites of applications
from the same developer where
it makes sense that they want
to have a scratch base on
disk that they all share
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or that they want to be
able to do direct IPC.
And another very common use
case is apps that have a helper.
For instance, a login item
that runs every time
the user logs in,
even when the main
app is not running,
and then when the main
app starts running,
it wants to be able to somehow
establish direct communication
to the helper that's
been running in the menu.
So, to solve that problem,
we have a mechanism
called application groups.
The idea is it's just another
Entitlement that you can put
on multiple apps or an
app and its helpers.
And it's prefixed by your
Apple Team ID and, after that,
it's whatever name you want.
And applications that have the
same application group name get
to directly communicate and
share file system locations.
So here's what that looks like.
Normally we have an app,
it gets its own container
and it can access that
container just fine.
And here we have a helper,
maybe as a login item.
Well, our main app can't access
the helper's container directly.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The Sandbox prohibits this.
But, if we create an
Entitlement, and we say,
here we're actually
going to put this
into myApp application group,
and we place that Entitlement
on both our app and our helper.
Now a shared location comes
into being on the file system
that both of these
can access directly.
In addition, as I mentioned,
certain IPC primitives like mach
and posix become available
for establishing direct
communication channels
between the app and the helper
or between different apps
in a suite where apps
share an application group.
We have an API called
SMLoginItemSetEnabled
that is fully App Sandbox
compatible that will allow you
to run your helper as a login
item every time the user
logs in.
Normally the fact that the
Powerbox only provides access
to the file or the folder
that the user selected is
exactly what we want both
for the security properties
of App Sandbox and because
that sort of makes sense.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But there are some cases
where you want just a
little bit more access.
So one example since we used
TextEdit as our demo app,
TextEdit, as you probably know,
when you create a new document
creates a Rich Text Format
document, an RTF file.
But, if you drag a picture
into that file, TextEdit needs
to basically turn the file into
a directory, change its name
from whatever the name was .rtf
to whatever the name is .rtfd
so that it can basically
store these attachments
in the directory.
And normally, that
wouldn't work because trying
to rename blah.rtf
into blah.rtfd,
the Sandbox would
be prohibiting this.
The user did not give you access
to blah.rtfd so you can't do it.
So to solve this problem in a
specific narrow set of cases,
we have a facility
called Related Items
that lets you express
certain relationships
between file names
and their extensions.
And in this case, you can
specify that RTF is related
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to RTFD so that if the user
gives you access to blah.rtf,
you can also use
NSFilePresenter methods
to obtain access to blah.rtfd.
This is how TextEdit does its
rename and there are a number
of similar use cases like
movie players wanting
to access subtitles which
are normally named the same
as a movie file but with a
different file extension.
This also requires a declaration
of which patterns are allowed
in the info plist and we
have some documentation
that shows you how to do this.
OS X for a long time has been
the best platform for automation
and rich automation
that there is.
And while App Sandbox never
imposed any restrictions
on how Sandboxed apps can
be scripted by the user,
it did impose rigorous
restrictions
on how Sandboxed apps
can script other apps.
And the reason for
this is pretty obvious
if you think about it.
If you have a Sandbox and
it's enforcing all these tight
restrictions, but the Sandbox
allows a Sandboxed app to go
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and script Finder or Terminal,
then there's effectively
no Sandbox, right?
You can get those apps
to do pretty much anything
you want on the system.
What we did is we created a
mechanism called Apple Event
Access Groups that allows
scriptable applications to mark
up their scripting
definition and say
that certain groups
of events are safe.
They're safe to be
invoked by Sandboxed apps.
And this works for,
if you're familiar
with scripting definitions,
sort of the full richness
of that definition mechanism so
commands, classes, properties,
you name it, all of them can
be grouped into access groups.
So this is documented, then you
can take a look at how it works.
But it's also used by a number
of OS X apps already so,
for instance, Mail has
an access group called
com.apple.mail.compose
which means that now,
even if you're Sandboxed, you
can use scripting to ask mail
to pop open a compose window and
put some information in there
and get ready for the
user to send E-mail.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
iTunes, similarly, has a
number of access groups
that you can use to
control the playback
or access library information.
And so the way this works is
there's a new Entitlement called
Scripting Targets where you
list for every app that you want
to be able to script
which has access groups,
you list which access
groups your app wants
to be able to use.
For example, here's
the Entitlement,
if we want to script Mail, we're
going to say in this dictionary
that mail is the only key and
that its value is an array
which contains, in this case,
just one access group called
com.apple.mail.compose.
Now it turns out that
there's one other familiar way
of doing scripting that a lot of
OS X apps want to be able to do
which is allowing the user
to select scripts that run
in reaction to certain things
happening inside the app.
Timer app might want to be able
to run a script when
the timer fires.
Mail actually supports
you saying
that when a certain mail rule is
triggered, a script should run.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Aperture allows you to set that
a certain script should run
after all your photos
have been imported.
And, traditionally,
this would mean
that the script is actually
executed by the application
which means, of course,
that it's subject
to the application Sandbox.
This is really problematic.
If the user is writing
scripts and expects to be able
to do whatever they want in
the context of the script
because the Sandbox will
simply prohibit those actions.
So we have a mechanism
called NSUserScriptTask
that now fully supports this.
And the way this works
is there's a folder
in tilde Library called
Application Scripts.
Under that folder, there's
a subfolder for every app
that wants to use this
facility and any scripts
that the user drags into this
folder, the per app folder,
that app is then allowed to
ask the operating system to run
with no Sandbox restrictions.
So the app can use API to
reveal that folder and Finder
and tell the user, if you want
to be able to run any scripts,
just drag them in this window.
Once that happens, those
scripts can run uninhibited
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by the Sandbox.
So this is part of
Foundation, the thing to look
up in documentation
is NSUserScriptTask.
It supports all of the
scripting that you might care
about so anything from just
shell scripts to AppleScript
and even Automator
Workflows and there are ways
to customize exactly how
you want this to work.
There's no Entitlement
required to use this,
you can just simply use it.
Previously it was the case
that iTunes maintained an
XML file that, basically,
described all the information
about songs and other items
in the user's media library.
And this is still the case,
but if a Sandboxed app tried
to parse this XML database,
it would work fine
unless the user had songs
and other media outside of
their normal media directories.
So if they went into
iTunes and said I want
to manage my own library and
have songs on Network Volumes
or different disks and so
forth, then Sandbox apps,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
even though they could
find the paths of the songs
and the items they cared about,
they couldn't follow them
because the Sandbox
would not allow it.
With iTunes 11, there's a
great new framework called
iTunesLibrary.framework
that actually provides a great
Objective C API that you can use
to never have to parse
a line of XML again.
You can simply ask
it for contents
of the user's media library.
You can ask it to gain access
to those actual files on disk
and what comes back
from the API,
just like with security
scoped bookmarks,
are security scoped
URLs so you can say,
I want to play this song, use
the API to request access,
you'll get the URL,
you'll call startAccessing
SecurityScopedResource on it
and the file is made available
within your Sandbox
and you can behave
like you always have
towards that file,
regardless of where it
is on the file system.
To use the iTunes Library
framework from a Sandboxed app,
you need the normal music
entitlements that have been
around since App
Sandbox launched.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
As I'm sure most of you know,
using App Sandbox
is now a requirement
in the Mac App Store.
And this has been, for the
most part, very smooth.
Most of our developers have had
no trouble adopting their apps
just like I've shown you with
very little time spent in Xcode
and just finding the right
entitlements to enable.
But, as we've been doing
this for some time now,
we've also picked up a bag
of tips and tricks for things
to check when you're
submitting your app especially
if it's for the first time.
And the first of those, and the
most important one I'm going
to point you to, is a document
called "Technical Q&A QA1773."
So if you search for that,
you'll find the whole document
that actually lists a number of
sort of common issues and tips
and tricks for when
you're submitting your apps
to the Mac App Store and
need to enable Sandboxing.
But I'm just going to
point out a few of them
that I think are the most
common kinds of things
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that you might run in to.
So the first is this, when
you're submitting your app
and you know it must
be Sanboxed,
that's not just your
main app binary,
it's actually every executable
file that you're submitting.
Now most apps actually just
have their main binary,
their main executable, but if
you're including XPC services
or if you're including
helper tools that you run
through things like NSTask, all
of those must also be Sandboxed.
The entitlements you choose must
match your app functionality.
Remember that there's a
human reviewer that's looking
at your app and if it's a
timer app that just, you know,
lets you set some
timers and then they fire
and some music plays and it's
requesting an entitlement
for access to the Address Book,
that reviewer is going to say,
well, what's going on here?
I see no way that this app needs
access to the Address Book,
why is the developer
requesting this entitlement?
So that can add time to the
review process and you'll have
to explain why you're
doing this.
In general, don't be tempted
to enable entitlements
that you don't need,
really only enable the ones
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that your app clearly
has need for.
And, hand-in-hand with that,
I showed you the process
of looking for Sandbox
violations.
Now, not all Sandbox
violations are bad.
And what I mean by that is, if
there's no functional impact
on your app whatsoever, if
you're seeing a violation,
everything in your app is
working fine, that's fine,
you don't have to do anything.
You don't have to go through the
list of entitlements trying to,
hoping that some random
unrelated entitlement will make
the Sandbox violation go away.
Because it might, but then,
when it comes time to submit
to the Mac App Store, it's
going to be a raising eyebrows,
why do you have this random,
unrelated entitlement?
Just the fact that there are
violations is not a problem.
It's only when the violations
are causing functionality
in your app that doesn't work,
that's where you go and you try
and figure out what entitlements
you might be missing.
And so, on a very similar note,
when you do request
entitlements,
try and make sure you
understand exactly what they do
and why you need them.
There are a few entitlements
that lots of you are requesting
that we can kind
of figure out why,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but it doesn't fully match the
model so here's an example.
If your app needs to be
able to open documents
from a USB stick the user
has plugged into the machine,
you don't need any
entitlements for that, right?
The Powerbox will just
let you browse there
like any other file
and that's it.
No entitlements needed.
That would not be reason
to specify the USB
Device Access Entitlement
because that entitlement
actually lets you interface
with custom USB devices that may
be connected to the computer.
It has nothing to do with
file access and USB sticks.
Similarly, if your app does any
networking, it's really tempting
to just check both of the
network entitlement boxes.
The one that says,
Inbound Connections
and Outbound Connections.
But actually, the most, the
vast majority of apps only needs
to be able to make
outbound network requests,
meaning it only needs the
client network entitlement.
Most of apps are not sitting
and being network servers
where they bind the port and
wait for inbound connections.
That's not what most apps do so,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
if you're selecting the
server networking entitlement,
make sure you actually need it
rather than just being something
that sort of seems
like you might need it.
Finally, we have this mechanism
we call Temporary Exceptions
which are a way to,
in certain cases,
where the Sandbox is
prohibiting functionality
for which we want the support,
but currently don't have a
good mechanism, there's a list
of temporary exceptions that
you may be able to request
that would allow your
app to continue working
until a better mechanism
is available.
And there's a few things
I want to say about this.
The first is there's been some
trepidation about the name,
Temporary Exception,
because it sounds
like maybe it'll just stop
working all of a sudden.
And, if you've distributed
your app and a bunch
of users have bought
it, suddenly one day,
maybe it just won't run anymore
because the temporary
exception has expired.
That's not how it works.
The Temporary Exception,
if you are approved,
the Temporary Exception,
it'll continue working
and it's simply that, at
some point in the future,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
as a better mechanism becomes
available, you may be asked
to no longer submit
new versions of the app
to the App Store carrying
that temporary exception.
But, you don't have to
fear temporary exceptions.
Once you request them,
once they're approved,
they're going to keep working.
There's no issue
about this breaking.
The second thing, and this
is a really important one,
is temporary exceptions
are not a way
to effectively disable
the Sandbox.
So we've seen some
very creative use
of temporary exceptions
including popular ones
like asking, you know,
for a temporary exception
to script Finder and Terminal
or for a temporary exception
that allows access to slash and
everything underneath which,
basically, means the
entire file system.
So remember, again, that when
you do this, it's going to go
in front of a human reviewer
and they're going to be unhappy.
So these are not a mechanism
to work around the Sandbox.
App Sandbox, ever
since we introduced it,
in Lion has been
a strong barrier
against exploitation and, even,
against pathological
coding errors.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It tries to drive security
policy by user intent,
instead of explicit security UI.
It's a technology for those
of you who are looking
at Gatekeeper and Developer
ID that's complementary
to Gatekeeper so you can, even
if you're distributing your apps
through Developer ID, you
can use App Sandbox with it.
We have some really great
documentation covering almost
everything that I
talked about today.
There's sample code where you
can look at things like XPC
and Sandboxing and XPC services.
But the real takeaway for me
is this, probably almost all
of you here are iOS users
and iOS, as we announced,
has asked 50 billion
app downloads.
Every single one of those
has run in the Sandbox
and our users have loved
that the carefree experience
they have of trying new apps.
They never worry about what's
going to happen to their phone,
they never worry about, you
know, what if it crashes
and deletes all my things.
Those are simply not in the
vocabulary of our iOS users
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
because the Sandbox,
from day one,
has imposed strong restrictions
on what apps can do.
And we would like to
delight our users on OS X
with the same carefree
app experience.
Thank you.
[ Applause ]