Monday, August 21, 2023

Bypassing App Management With TextEdit

Jeff Johnson (Mastodon):

In retrospect, I regret participating in the Apple Security Bounty program. It has been a giant, frustrating waste of time, and I wish I had just dropped this 0day on October 24 of last year when Ventura was released. I suspect that if I had done so, Apple would have found a way to address the issue already in Ventura. Thus, I feel that my prolonged silence has not protected Mac users. The standard practice in reporting a security vulnerability is to give the vendor 90 days to address the issue, and I’ve given Apple vastly more time than expected.

[…]

I discovered—almost by accident—that a sandboxed app could modify files that it shouldn’t be able to modify: files inside the bundle of a notarized app that were supposedly protected by App Management security.

[…]

This isn’t the first time that a major macOS update included a new security (theater) feature with a gaping hole. For example, I previously discovered a bypass for Mojave’s new privacy protections. And it’s important to keep in mind that I’m not a professional security researcher.

It’s hard to make a living reporting security bugs when Apple has a history of declaring them not bugs, being stingy with payments, and stalling—which encourages releases like this that forfeit the possibility of collecting a bounty.

Jeff Johnson:

Today I want to illustrate the vulnerability a little more clearly to a non-developer audience.

[…]

As you can see, modifying that file would mess with Firefox’s software update mechanism, perhaps leaving the user vulnerable to a malicious software update.

[…]

TextEdit is sandboxed. Ironically, sandboxing was designed to prevent attacks, but in this case it allows an attack. That’s the bug, the vulnerability. A sandboxed app can modify a file that is supposed to be protected by App Management.

[…]

This has all been just for illustration. It wasn’t a real, viable attack, because I had to do everything manually. However, my disclosure yesterday presented an example of an automated tool that could execute a real attack.

Thijs Alkemade:

When I looked at this feature before Ventura was released I immediately found 4 different ways to bypass it. It really looks like it hasn’t been tested at all, as every potential method I’ve thought of worked. But bypassing by using a sandboxed app was not something I could have imagined working. 😂

Previously:

10 Comments RSS · Twitter · Mastodon

Paul F. Simmons

This is not any kind of security vulnerability. Apple uses a concept called "user intent". This is the same as allowing a user override of Gatekeeper, turning off SIP, or even giving an app Full Disk Access. If a user intends to modify a file, and they have the appropriate permissions, then the operating system will let them do that.

The open panel is actually a system proxy process that punches a hole in the sandbox for the app. Otherwise, sandboxed apps wouldn't be able to access user documents. It is essentially Full Disk Access for a single, user-selected file.

This is basic macOS programming. It really makes me question the motivations of people who would either publish the message in the first place, or amplify it.

@Paul I think you’re misunderstanding this. It’s not about user intent. If you look at the sample code, the user-entered path is not used to grant sandbox access. It’s just used by the unsandboxed app to pick which file you want to edit for demo purposes. In a real attack, the file would be chosen without user interaction.

> This is not any kind of security vulnerability.

Apple considers it a vulnerability. I've been in communication with Apple Product Security, and they wanted me to keep it confidential until it was fixed.

> The open panel is actually a system proxy process that punches a hole in the sandbox for the app.

There's no open panel involved. My sample app has a text field where you enter the path of the file you want to modify. And the text field only exists for the purposes of demonstration; an actual malicious app could do everything automatically, silently.

> This is basic macOS programming.

I've been a professional Mac developer for over 15 years. Check out the rest of my web site.

Care to apologize now, Paul?

@Michael No. I didn't look at the sample app that consisted of a sandboxed app bundled inside a non-sandboxed app. I thought the TextEdit example was more interesting. You thought so too. That's why you used TextEdit in the title of your post.

> Apple considers it a vulnerability. I've been in communication with Apple Product Security, and they wanted me to keep it confidential until it was fixed.

I'm not privy to any Apple communications regarding your claims. Maybe you did find some odd edge case involving recursively bundled apps signed by the same developer on said developer's machine. If so, Apple's assessment of your bug bounty's value was accurate.

> There's no open panel involved.

There is definitely an open panel involved with TextEdit. Had you just left it at the convoluted example code, I would have ignored it like Apple did. But even if you did find some odd edge case, why would you think, or claim, that TextEdit's open panel demonstrates the same issue? That's the interesting part here.

> I've been a professional Mac developer for over 15 years.

I actually thought you had more experience than that. But even with only 15 years experience, this doesn't add up. Sorry!

@PF I think the TextEdit angle is interesting for two reasons: (1) you can test it out yourself, without having to install anything or look at the code, and (2) it demonstrates the issue, which is that it’s unexpected that a sandboxed app would be allowed to make these changes when a non-sandboxed app doing the exact same thing would be blocked.

To answer your question, I think TextEdit receiving a file to open via Launch Services adds a sandbox extension in the same way that an open panel does.

The sample code does not involve two apps signed by the same developer, and AFAIK the nesting is not a requirement either. I don’t really see this as an “odd edge case.” I think it’s more of a hole.

Paul, your willful ignorance and lack of reading comprehension seem to have no bounds.

> If so, Apple's assessment of your bug bounty's value was accurate.

Apple made no assessment of my bug bounty. As I explained in the blog post, Apple's policy with the security bounty program is to calculate the bounty only after the fix is released. They apparently never do so beforehand.

> I would have ignored it like Apple did.

Apple did not ignore it. After all, I was credited with CVE-2023-32357 (among others). Clearly, though, Apple hasn't prioritized a fix, which is why I went public.

> There is definitely an open panel involved with TextEdit.

Again, there is not.

> why would you think, or claim, that TextEdit's open panel demonstrates the same issue?

I did not. In my illustration, which you would have seen if you read it, there was a command-line invocation (which could come from a shell script as easily as from a person typing):

% open -a TextEdit /Applications/Firefox.app/Contents/Resources/update-settings.ini

My sample app uses the API -[NSWorkspace openURLs: withApplicationAtURL: configuration: completionHandler:], which is basically equivalent to the "open" command. No user interaction or intention is required here, and no open panel.

> But even with only 15 years experience

I said over 15 years.

Here's a dumb question: _why_ do sandboxed apps have full access to /Applications? That sounds like some odd legacy thing?

@Sören By default, sandboxed apps only have read access to /Applications. It makes sense for basic interoperability, e.g. to check a version number or get an icon.

I'm a fairly technical user who has read both blog posts and I'm still not clear on what the vulnerability is exactly. It would be helpful to explain this in terms of what an actual attacker (presumably the author of a sandboxed app) would be able to do that they shouldn't. The example in the second post of using the open command from the terminal doesn't seem like a practical attack (I assume a sandboxed app cannot call open the same way a user could).

[1]: https://lapcatsoftware.com/articles/2023/8/2.html
[2]: https://lapcatsoftware.com/articles/2023/8/3.html

@Nick The attacker writes two apps (one inside the other, so it’s a single download). The inner app is sandboxed; the outer app isn’t. The outer app can see where the files are but doesn’t have write access because they’re protected by App Management. It then uses the API-equivalent of open to pass them to the inner app, which inappropriately gains write access to them.

Leave a Comment