Monday, April 19, 2021

Mac App Store Entitlement Folly

Jeff Johnson:

Xcode has been pushing the “com.apple.security.files.user-selected.read-only” entitlement on us for ten years, and this seemed fine with the App Store too all these years… until a couple days ago. If it turns out that “com.apple.security.files.user-selected.read-only” is unnecessary for my app, and Apple wants it to be removed, then I am happy to remove it… in a reasonable amount of time. But I won’t tolerate a metaphorical gun put to my head, forcing me to remove the longstanding entitlement immediately on threat of not being able to release an app update that’s important to me and my customers. So I’m going to fight that. I did fight it, and I “won”. At least I won this battle, if not the war. In any case, there’s a kind of insanity in rejecting an update for an entitlement already possessed by the version of the app currently available in the App Store.

[…]

For App Store customers, the lesson is that you ought to be very skeptical about App Store review. After all, if I can argue an app reviewer into accepting my submission despite their reservations, then so could a scammer! Note that I never actually explained to app review why I needed the entitlement.

Previously:

Update (2021-05-03): James Thomson:

Got a metadata rejection for Dice because they don’t like the screenshot I used for the sticker pack because it “doesn’t show the app in use”. But it’s not an app, it’s a single sticker.

[…]

It would be churlish to point out that I’ve been using this image for the last 18 months without a problem…

24 Comments RSS · Twitter

Old Unix Geek

Probably just a new, wet behind the ears, but very assiduous, App reviewer.

There are a lot of things to dislike about the App Store but this whole exchange seems entirely reasonable to me.

I think it's nice that a reviewer noticed this app didn't need an entitlement and flagged it for removal. It's ultimately a good thing if apps don't have entitlements they don't need. And it's also reasonable that Apple gave the developer more time to remove it, without putting a "gun to his head" or other hyperbole. This entitlement isn't dangerous; it doesn't give apps carte blanche access to files.

There are a lot of ways the App Store is broken, but this is a contrived example. Haggling over the timeline to remove a benign entitlement because an App Store reviewer was trying to help improve an app seems unremarkable.

"I think it's nice that a reviewer noticed this app didn't need an entitlement and flagged it for removal."

Rephrased: You think it's "nice" that the reviewer rejected my update, preventing me from shipping it to customers?

"And it's also reasonable that Apple gave the developer more time to remove it"

This is not an accurate description of the situation. After I argued, the reviewer simply approved the submission without any future requirements. I don't have to remove the entitlement at all, as far as I know.

Kevin Schumacher

I’m not the person you’re replying to (and I don’t necessarily agree with their characterization of this situation), but as seems typical given what I’ve seen quoted from you on this website over the years, you are greatly exaggerating what happened.

Please show, with a quote from the original App Review email, where your update was actually rejected, as in, “Your update will not be posted to the App Store.” It was not. They simply requested more information. One way you know this is one of the paths they gave you involved doing a developer reject of the update. If they already rejected it, then what would the developer reject be accomplishing?

What is troubling here is not the fact that they requested more information, nor that they, according to you, rejected your update (which they did not), but that you were able to talk your way out of it without actually answering the question. That’s what should be the focus here.

Nobody was holding a gun to your head, metaphorical or otherwise. They asked for information, period. The things you report would have a lot more impact and be less ignored if you could manage to stick to the facts, which are often problematic enough on their own without inflammatory rhetoric.

@Kevin I do agree about putting some focus on the “talk your way out of it” part. But I think the bottom line is that the update was blocked, and it matters very little whether it was held in stasis vs. rejected.

"Please show, with a quote from the original App Review email"

App Review does not communicate by email. You would know that if you were an App Store developer, which you're clearly not. Thus, one has to wonder where you get the confidence of your assertions and accusations.

Kevin Schumacher

@Jeff No, I'm not an App Store developer, nor have I ever claimed to be. I made a single error in wording. Substitute "response" for "email" and the rest of my post doesn't change. You would know that if you were interested in having a substantive discussion of the facts, which you're clearly not. That you are hyperfocused on that single word would seem to indicate you have no response or defense, or desire to attempt to respond, to the actual meat of my argument. Thus, one has to wonder where get the confidence of your assertions and accusations.

@Michael I honestly think it does matter. The fact the update's release was delayed over it is perhaps an issue, given that the currently-shipping version contained the same entitlement, although it could simply be a reviewer who made a mistake (which seems likely given how easily, without any change or substantive response, the update was subsequently approved). And of course, Apple is not going to admit a mistake like that, so approval without further issue is their only response.

But I think rejected has become a highly-charged term that means a specific thing in this context, as in cases where Apple has completely and totally rejected an entire new app (or update) based on a random re-interpretation of a guideline.

The difference is in the form of the response from App Review. Consider "Your app does X, Y, and Z which are not appropriate for the App Store and therefore your app/update will not be approved," with no real recourse and denied on appeal, or at best, only approved once one runs to the press/social media. That is a far cry from "Can you please explain why your app needs Q entitlement? Because I couldn't find why it does." I do not think requesting more information about usage of an entitlement that ultimately does actually affect privacy is in any way the same thing.

And the ironic thing here is this type of response is exactly what we should be BEGGING App Review for. Again, honest discussion to be had about delaying updates over things that exist in currently-shipping versions.

Although even here, the argument could be made that if they are questioning why the app needs the entitlement, if it is then found that the app doesn't, perhaps the currently-shipping version is then pulled, too. But if they pulled the current version contemporaneously with asking the question, there would be even more of a furor over Apple retroactively rejecting updates. And I would agree with that anger.

But App Review SHOULD be questioning--internally initially, and then directly with the developer, if necessary--if apps really need the entitlements they have. They should be saying, I can't find where it affects how your app operates. Tell me more.

Old Unix Geek

One could argue there would be a reason to reject Jeff's update if Jeff added a new entitlement. However he didn't. Particularly if this entitlement is added by XCode by default (I'm too lazy to check that for myself). The fact the App Reviewer didn't know this demonstrates the quality of Apple's App Reviewer training.

Jeff's conclusion that App Review is security theatre is correct. Unless Apple were to actually code-review every single App it has to be, because of the Halting problem. A couple of zero-days would fit into a few hundred bytes of code. There's no way Apple could ever find them, since by definition, zero-days are code which breaks the confines of the sandbox and are unknown. (If they were known, one would fix the sandbox).

In other words, "App Review" can only deal with honest brokers, and can't find the actual criminals who break out of the sandbox. Just like the TSA confiscates toe clippers, but weapons get sneaked past them all the time. That's security theatre.

In its court case with Epic, Apple stated that to allow 3rd party App stores, it would have to change the hardware to provide higher security. They would have to provide actual security, but they obviously don't want to. It would be difficult and require rewriting some parts of their OS, I grant, but it would be real, not theatre.

My guess is that some of Jeff's cynicism comes from knowing how pointless App Review really is.

Kevin, my point in pointing out that you're not an App Store developer is that you seem to have some idealized vision of app review in your head — the "Schoolhouse Rock" version of app review, as it were — that doesn't reflect the sad reality we experience. Recently released court documents confirm what developers have known all along: that app reviewers are generally unskilled labor who average only a few minutes per review.

It literally said "Binary Rejected" in App Store Connect Resolution Center. We developers all understand what that means. I'm not going to avoid using the term "rejected" just to satisfy uninformed people who don't understand the process.

"If they already rejected it, then what would the developer reject be accomplishing?" Again, this comes from not understanding the process. If Apple rejects your update, then they won't publish to the App Store, and it's stuck in a kind of limbo until you can satisfy the app reviewer's demands in one way or another. (And not all rejections are for the app itself. Sometimes they'll object to something in your app store listing, such as the screenshots, a "metadata rejection". Then you just need to post new screenshots and don't have to upload a new binary.) Whereas developer rejection means essentially that you abort the whole update review process and start over from scratch. This can happen for a number of reasons; for example, if you submitted an update, it's still waiting for review, but you discover a new bug in the update while it's waiting for review. So you developer reject the binary, then fix the bug, upload a new binary, and start the app review process over again. You go back to the "beginning" of the review queue, and you may get an entirely different reviewer the next time. The only way to remove an entitlement from an app is to build a new version and upload it, hence developer reject is necessary in that case.

I don't expect non-developers to understand app review fully. However, I do expect them to refrain from mansplaining the process to developers with first-hand experience. And to refrain from accusing them of lying about it.

@Kevin In some sense there are different degrees of rejection, from metadata, to not correctly complying with a specific guideline, to an app whose entire conception is incompatible with what Apple wants. But that’s just our interpretation of what happened. Apple always uses the word “rejected,” and the only gradation I can recall is that sometimes you can talk for a while and have them look at the same binary again vs. “developer reject” and then starting over with a new binary. Yes, App Review should be questioning, but to your previous point about not answering the question, it’s not clear that’s really what happened here. That makes it just seem random.

There are very good reasons to criticize the App Store approval process, which is indeed opaque, capricious, and mostly pointless. There’s no real security being enforced by the review process. Those are all serious problems. But complaining about this particular exchange is making a mountain out of a molehill.

A well-meaning (but perhaps overzealous) reviewer wanted to remove an entirely superfluous app entitlement. And so the app’s release was temporarily delayed, but ultimately approved, after simply explaining the situation. That sounds harmless to me. I think it's a mistake to hold up this trivial nuisance as some kind exemplar for why the App Store is broken.

"I think it's a mistake to hold up this trivial nuisance as some kind exemplar for why the App Store is broken."

Some of the weirdest comments on the internet are "This is not important." It was important enough for you to take the time and effort to comment. You could have shrugged, written nothing, and moved on with your life. Should I be insulted or flattered by these comments?

Now, I certainly don't take my example to be the primary example, or a primary example, illustrating why the App Store is broken. It's just one of countless examples. The primary purpose of my blog post was actually to inform my fellow developers that Apple may suddenly start rejecting apps with the aforementioned entitlement. However, I'll always take the opportunity to throw shade on the crap store. Also, I wouldn't call it "harmless" that my release was delayed more than 24 hours and would have been delayed even longer than that if I hadn't convinced the reviewer to pass me through. It's not a giant harm in the grand scheme, but we developers suffer innumerable, interminable minor harms all the time, along with the major harms.

Kevin Schumacher

So Apple uses 'rejected' to refer to a specific build submission that had something flagged during review, be it the entire concept or questioning an entitlement. OK. I didn't know that was the actual wording. Point conceded that they technically rejected the update.

That doesn't change my ultimate point, though. I stand by my earlier statement that there is quite a bit of daylight between asking for more information and denying the update outright, even if the binary is technically "rejected" (even if temporarily) in both cases. Given that that is a known state of affairs, then screaming 'My update got rejected' while they're simultaneously requesting more information is being disingenuous, at best.

@Jeff I did not accuse you of lying. I said you were exaggerating certain aspects of the situation to amplify what happened based on your desired narrative ('Apple held a gun to my head') instead of focusing on the actual details of what happened, which is that you got asked for more information and somehow talked your way out of it without supplying that information. The latter part of that is far more problematic than your update being put on hold until you responded.

As for you not changing words to satisfy "uninformed" people, then perhaps your paragraph directly addressed to App Store customers shouldn't even be in your blog post. Is the typical App Store customer intimately familiar with Apple's use of the word rejected while pending more information? This just reinforces the fact that you chose to say 'my update was rejected' while seemingly knowing that some segment of the people reading your article would hear it in the sense of the actual outrageous rejections that Apple has perpetrated.

@Michael You're right that it's not clear what actually happened here. That's why I think blowing it up into this 'my update got rejected!!!1' narrative is more harmful than helpful, because it obfuscates the rest of the discussion.

Now: "I did not accuse you of lying."

Previously: "Please show, with a quote from the original App Review email, where your update was actually rejected"

You demanded proof from me because... you believed me?

Anyway, I don't think "rejected" is a problem. I just think you have a conception in your own mind of what you think it means, but there's no reason to assume that you represent the views of anyone except yourself.

From the rejection notice: "In order to continue reviewing your app, we require additional information." This is not just asking for more information. It is refusing to approve the update unless I satisfy the reviewers demands. That is a choice. If they *just* wanted information, they could have approved the update *and also* asked for information. See the difference? A rejection and a request vs. an approval and a request. Completely different situations. Moreover, I did not even have the information they wanted. I don't know for certain whether my app actually needs the entitlement or not. It would require extensive testing to find out, as I already mentioned. So the delay for information would have been indefinite.

I don't think you're recognizing the biggest problem here: this entitlement was completely fine and unquestioned for 10 years, then suddenly, with no notice whatsoever to developers, no announcement of policy change, it's suddenly not ok, and Apple decided to hold up an app update over it. It's really the unwritten rules, and the changing thereof, that drives us nuts. It makes App Store submissions totally unpredictable, any small update could be a ticking time bomb that brings up a bizarre objection from Apple out of left field.

Kevin Schumacher

I didn't demand proof because I didn't believe you. I was pointing out that in the text of their request, at no point did they say anything like "Your update is rejected because you are using this entitlement," which one would certainly be excused if they came away from the majority of your post with that impression.

A lot of people have a conception of what rejected means. Rejected sounds final. Rejected sounds like "Nope, this is not going to happen." Rejected is not "In order to CONTINUE reviewing your app, we require additional information." Yes, I understand Apple marks the binary as rejected (temporarily). Apple's weird nomenclature aside, most people would not understand "rejected" to mean "delayed adjudication pending further information," which is how it is meant in this context. That's not just me, that's entirely redefining the word. And perhaps Apple did that in the way they handle these things.

But unless your target audience was solely App Store developers who have experience with submissions being "rejected" while requesting additional information, you're going to have people who are not familiar with rejected in the Apple sense that you are trying to use it. (And we know that was not your sole target audience, for reasons mentioned previously.)

As much as you try to pretend it is, that's not just me. When I want a sandwich at McDonald's, they REQUIRE payment to continue reviewing and then preparing my order. Is that them rejecting the order until such time as I submit the required payment? Or is that them putting the order into a pending state until I arrive at the window and swipe my card? I think you are well aware what most people would say.

As far as Apple "not just asking" for more information, it was not a demand that you change your app's name to Little Bo Peep's Hair Detangler. It wasn't even a demand for you to submit an updated binary immediately without the entitlement or your app would be pulled entirely. The reviewer's "demands" was for you to help them understand why your app needs an entitlement, full stop.

Whether the update should have been approved in the meantime is an honest question. But acting like the reviewer was "demanding" that you steal the nuclear launch codes from the White House, or they were, say, holding a gun to your head, is doing what I previously stated--blowing the situation out of proportion.

(You never really address it precisely in your post, but the prior version of your app, the one that was shipping at the time you submitted the new update--did it have a crashing bug or something else that was impeding your customers from using it? If it did, that should factor into whether an update is held up for this type of thing. My understanding is, though, there is a way to mark updates as such when submitting them, so assuming that is true and yours was not, we have no way of knowing what the outcome would be in that kind of case.)

The fact you don't have the requested/demanded details should not really be the thing that you are relying on here. I understand you are saying that it is a default that is applied by Xcode. But I don't buy that that gives you a free pass for not knowing whether your app needs it, especially if, as you say, this has been a thing that Xcode has been doing for years and years.

Literally the only thing here that you and I agree on is that it's very odd for this to come up out of nowhere after however many updates you have submitted of this app.

Kevin Schumacher

I typed up the long response above and I'm going to post it because I spent some time on it, but I'm going to also just post this because this is what it boils down to for me. And then I'm done with this.

"But I won't tolerate a metaphorical gun put to my head, forcing me to remove the longstanding entitlement immediately on threat of not being able to release an app update that's important to me and my customers."

Literally nobody was forcing you to remove anything. They (asked/demanded/required/whatever word makes you feel good) additional information about your use of the entitlement. That's it.

That's where your entire post fell apart.

Kevin, my update was literally rejected because I am using that entitlement. There is no other reason it was rejected. It's pure insanity and reality denial for you to say otherwise.

You're also denying reality about the word "rejected". It does not in fact imply finality. An idea, a proposal, an application, these kind of things can all be rejected, yet you can keep trying, and maybe next time you won't be rejected. It's actually you who are redefining the word. Rejection does *not* imply that you can't try again. Again, this weird definition is all in your head and not in anyone else's head.

"Literally nobody was forcing you to remove anything."

You're missing the headline, which was "Guideline 2.4.5(i) - Performance". Every App Store rejection cites an App Store rule that the submission violates. In this case, "2.4.5 Apps distributed via the Mac App Store have some additional requirements to keep in mind: (i) They must be appropriately sandboxed" https://developer.apple.com/app-store/review/guidelines/#hardware-compatibility

You're also focusing on the one paragraph of the app reviewer's rejection notice and ignoring another: "Apps should have only the minimum set of entitlements necessary for the app to function properly. If there are entitlements that are not needed, please remove them and submit an updated binary." This is not a request for information, it's a request for action.

The implication is very clear from the rejection notice: either prove that the the app is using the entitlement, or remove the entitlement. I managed to talk my way out of doing either of those things, but my "solution" was not one of the two options given.

"Literally the only thing here that you and I agree on is that it's very odd for this to come up out of nowhere after however many updates you have submitted of this app."

That's the most important point! If I were submitting a new app for the first time, I wouldn't have a complaint. 15 consecutive approvals of this app, and many other approvals of other apps over the years, and then all of a sudden I'm stuck out of nowhere. This is exactly my main complaint, and you admit it's a problem.

Old Unix Geek

This makes for depressing reading: https://www.scribd.com/document/505173765/Epic-Games-Depositions-in-Epic-v-Apple#download&from_embed

Basically the qualifications of people who review the apps we code, according to their boss, is "can breathe" and "from all walks of life"... No knowledge of programming whatsoever. So much for App Review guarantees customers' safety. It's quite unsurprising hacks make it int the store: the app reviewers wouldn't know Turing's Halting Theorem if it hit them in the head. The App Store is even more of a joke than I could possibly have guessed. Just based on that, it seems to me that Apple should be sued for false advertising.

> the app reviewers wouldn't know Turing's Halting Theorem if it hit them in the head.

I didn't exactly expect app reviewers to be software engineers, nor do I think that would make sense. Hopefully, they're halfway decent from a QA perspective.

Old Unix Geek

"Can breathe" is a sufficient qualification to determine whether that app is hacking you, is it, Sören?

If so, there's no need to employ anyone to do that. Users can do that quite well themselves.

Also I have no idea why you think they're doing Q.A. They're deciding whether an app will be published. That's not Q.A. which is finding bugs, incompatibilities, etc.

I don't know what your point is, but mine is that Alan Turing isn't relevant for checking an app for whether it meets the guidelines. There's plenty to criticize about the App Store, but "many of the reviewers can't even write code" ain't it.

Old Unix Geek

Apple claims App review is necessary to ensure that Apps in the store are "safe" for customers. The whole reason other stores and side-loading are forbidden is for the safety of Apple's customers and the phone carriers. And it's basically the value proposition behind the App Store: you're not buying from some rogue developer, you're buying from us, we're trust worthy, and we checked the apps we sell.

To this end, programmers are told that they must not use certain APIs, must not use a Javascript interpreter other than Apple's, and should not use hacks to escape the sandbox. Supposedly this is all checked during review. Usually the whole point of enforcement is to ensure that those people who are inclined not to follow the rules must do so.

All this stuff cannot be automated. That's essentially what the Halting theorem says: you can't even automate a simpler problem, namely does this program halt? Therefore people should be looking into apps that seem odd, where perhaps some automation helps detect that they seem odd. Since proving all of this is actually harder than simply showing that an App terminates, I'd expect that the people doing the checking would know something about security / programming / computer science. So, I'd expect that if Apple were truly making an effort to do what it says it does, it would employ such people.

Instead it employs people whose qualification is that they can breathe. If this does not strike you as hypocritical, I don't know what would. It means that Apple's promise of safety to customers is a bare faced lie in that any competent evil-minded programmer can run circles around Apple's "enforcement". It basically guarantees that nothing actually unsafe will be detected, only surface bullshit, such as "Did you use a picture of our iPhone in your app? That's forbidden!".

That Epic could flip a switch in the server response to ask to be paid wasn't proof that it was lucky to sneak past the reviewers. It was proof they don't even check for that. That nice safe app you installed for your ageing mother? It could convince her to send over a photo of her social security card tomorrow. That app your kid downloaded? It could include a two-way communication channel for pedophiles to groom her and extract photos out of her. In my book, Apple just admitted they don't check for any of this. I'm not sure that is what the average user thinks is happening when she buys an app from the Appstore.

Old Unix Guy

I should have said "seems to me to be a bare faced lie". Obviously I don't know everything Apple is doing these days. Hopefully they're doing a whole load more than was said in the testimony. I'm guess that I'm just really shocked the testimony I linked to says they do so little.

Old Unix Guy

I also should not have said "Apple just admitted..." but used the name of the higher up guy who used to work for Apple who said it in his testimony but I don't have time to go back and reread those 123 pages and I've forgotten who it was.

Leave a Comment