Hacker News new | past | comments | ask | show | jobs | submit login

What's bullshit about banning someone who has been notified that they are in violation of the rules and then tries to hide their use of private APIs rather than stop using them? That's exactly what I would do in Apple's position. Resubmitting the same thing and hoping that it doesn't get caught the next time isn't an honest mistake.



> then tries to hide their use of private APIs rather than stop using them [...] Resubmitting the same thing and hoping that it doesn't get caught the next time isn't an honest mistake.

This is missing the point of the post you are replying to. Say you identify five closed API dependencies and remove them. Do you resubmit? If you missed any others, you and all your apps might be banned.


They do not ban you for removing some uses of private APIs, but missing others and resubmitting. In the last decade of this being the policy on the iOS app store they've been quite consistent about only banning people who very clearly are deliberately trying to sneak things in.


> They do not ban you for removing some uses of private APIs, but missing others and resubmitting.

Maybe not -- maybe you know something about how Apple operates. But clearly they ARE sending responses threatening to do exactly that.


> maybe you know something about how Apple operates

Anecdotally, I have never heard of this happening in non-malicious cases, ever. And I know a couple hundred Mac and iOS developers who would raise a lot of noise if this did happen, so I'm inclined to believe that it doesn't.


Because in the past, developers have obfuscated their use of private APIs rather than removing them. They are threatening to ban people who abuse the platform. They aren't going to ban anyone making an honest effort to eliminate their use of private APIs.


Where as on Windows there is no such issue.


Yep - instead, Windows is dragged down by 20-40 years of bug-for-bug API compatibility, even in the things that were never documented as public API and pretty clearly look like internal solutions that the author at Microsoft never designed for public use.

There is a good reason for how Apple approaches use of their private APIs, and for how Microsoft approaches use of their private APIs. Not saying either one is correct, there really is no answer, but consider that for any public API that exists, there may be undocumented details that some software somewhere relies upon whether they realise it or not. Apple is just taking a more aggressive approach than Microsoft here by detecting and disallowing private API use in their store so as to avoid issues down the line.


As far as I know, the Microsoft Store has a similar-sounding check for "unsupported" APIs. I don't know the details though.

[1] https://tedwvc.wordpress.com/2013/07/19/finding-the-kernel32...

[2] https://github.com/golang/go/issues/21805


There's no issue here for a Mac either (this was for a submission for a macOS program). The problem was when submitting it to the Mac App Store.


They can ban you for absolutely any reason whatsoever. They can ban you for using the number "4" in your code.

They don't, though. And we trust them not to, because it is not reasonable behaviour and it would absolutely not make sense for them to do this.

This is the same.


Yes, you resubmit.


How exactly do you miss a dependency?! If it's not your code, then it's a dependency that you need to look at.


Dependencies of your dependencies! Imagine installing a library that depends on a couple dozen libraries in its own right. You may not have time to inspect every single node in the dependency graph.


As an end user, can I just say how uncomfortable I am at the idea that some app on the App Store includes some node.js dependency where the app developer has no idea what's in it? What if it's event-stream?

If you're sending me code to run on my computer—especially if I'm paying for it—you either need to have glanced at the code yourself or have some reason to trust what's in there (it's from a company you have a business relationship with, it's a major library from a known author that other apps on the store are also using, etc.). Otherwise you're being irresponsible. If you don't have the time to look at the library, don't use it.


I'm a developer, and knowing how this is the default is not something I particularly like, but it's really only in the most security/mission critical code that dependencies get thoroughly wetted.

You can fully expect that less then 1% of the apps in any app store has a transitive dependency chain that is fully known and understood by the author to any meaningful extent.

Most of that code is however understood by someone, although not necessarily the app developer. The sandboxing and app permission dialogue boxes are unfortunately a critical part of the defense against malicious code, although not a perfect one by any stretch of the imagination.


So never run Linux?


I get Linux from people I trust to verify source code and the source code of dependencies and to push back against dependency sprawl (Debian, in my case, and I'm on debian-devel and I happen to see every email sent for every new package; there's an overhead there). Others get Linux from a vendor they have a commercial relationship with (Red Hat, Canonical, even Oracle, etc.)

So, can you expand on why you think one should never run Linux?


Or only run Linux? *

* (any source available OS)


GP says not to run anything you haven't looked at yourself for the most part, paraphrasing. I doubt anyone has self audited all the software and drivers going into a desktop Linux distro.

The point is, at some point you stop digging


> GP says not to run anything you haven't looked at yourself for the most part, paraphrasing.

That is a highly inaccurate paraphrase of what I said. You can tell it's inaccurate because I'm specifically suggesting that end users should be able to trust apps on the App Store without auditing the apps ourselves, as long as we trust the app authors, and that app authors should bear responsibility for what they redistribute.


Desktop Linux distros have package maintainers and companies behind them like RedHat or Canonical.


GP says not to publish anything you haven't looked at (or OKed by appeal to authority). Publishing should be a higher standard than running.


> Dependencies of your dependencies! Imagine installing a library that depends on a couple dozen libraries in its own right. You may not have time to inspect every single node in the dependency graph.

Excuse me, are you, the developer, telling me, a user, that you don't know what you're giving me to run on my computer?


Hi my name is node_modules have you met me? If you invite me to a party I bring my 500 closest friends as my plus one!

I just looked at the node_modules folder for a project that runs user configured code when your imap server gets a new mail via imap idle. It's called imapnotify and inside its node_modules dir I see it pulls in 549 js files.

The majority are under 100 lines per file dozens are between 1 and 30.

Cutting just the last segment so that /foo/bar/baz.js and /bam/baz.js both appear as baz.js and removing dupes reduced the number of unique filenames to 383.

Basically every js dev is either telling you or not telling you that they don't know what they are giving you to run on your computer.


There are reasons forums known for being less diplomatic than HN often take delight in heaping scorn and ridicule on js devs. This is one of those reasons.


> If you invite me to a party I bring my 500 closest friends as my plus one!

That sort of thing is a big red flag that perhaps you should reconsider using that package.

But even if you do use it, that in no way reduces the fact that it's your responsibility to know what you're shipping.


That is every javascript package ever incidentally. Do you have an alternative suggestion as far as connecting to an imap server and responding to events? Not a library to write such a thing but an actual implementation.


No, I don't, but even if there are no such alternate packages, that doesn't mean it's OK to use one that you can't sufficiently understand.

If you can't find an acceptable package, then I'd absolutely recommend writing that functionality yourself. connecting to an IMAP server and responding to events aren't complicated tasks, after all.


This is entirely feasible but what percentage of people can write replacements for problematic tools and what tools can they afford to replace time?


Among software engineers? I would expect (hope?) that the percentage that could do this approaches 100.


How much extra time do you have to reimpliment things that work because you disagree with how they are written?


You misunderstand what I'm saying. This isn't about disagreeing with how anything is written, this is about the responsibility of developers to know what they're shipping.

If devs can't do things like be able to tell what dependencies a module/library has, then they shouldn't use that module/library.


With NPM as an example to fully know every dependency is a highly time-intensive and complicated task due to following:

* you can't be sure code in package is same you see on github as npm doesn't do signatures

* code already in node_modules is usually minified and obfuscated

So only real way to be sure is to make own repository, copy every dependency, check code, build own packages and only use packages from your repo. Repeat process when versions are updated.

So to answer your question, yes, 99% of apps, they don't know.


That's an excellent reason to avoid using apps.


I think that ship sailed a long time ago. Right now I'm building an app with Google's mobile toolkit, Flutter. Flutter itself is a few hundred kloc. And on top of that, I'm using a bunch of libraries; I wouldn't be shocked if it were the same amount of code again. Assuming I can properly code review a few hundred lines per hour, reviewing all that will take me a year or so. Which is maybe 5x what it will take me to ship an MVP.


You are missing the fact that dependency tree is constantly changing as dependencies get bug fixes and security patches, so in the middle of your review you will be forced to re-check.

Unless you are willing to freeze whole tree until review is done but then you don't get bug fixes and security updates for period of initial review + review of updated packages.


Is that a joke? Surely you aren't suggesting that developers should have full knowledge of all transitive dependencies that compose their application stack.


> Is that a joke? Surely you aren't suggesting that developers should have full knowledge of all transitive dependencies that compose their application stack.

This will be borderline impossible for a nodejs developer, but a perfectly realistic expectation for e.g. a Django project.


Honestly, it boggles the mind to think that a responsible developer would just pull in some 3rd party dependency without auditing what it does/calls and what other sub-dependencies it has, and then ship it as their product that their business relies on.

Everywhere I’ve ever worked, adopting a dependent library was a HUGE DEAL. You don’t do it lightly. You have to know what’s in it, know what it calls, know what the license is, understand the increased security attack surface, measure how much bigger it makes your binary, measure any performance deltas, and so on. In bigger companies, you need to get all sorts of approvals... Who the heck are these companies where you just hook up the git submodule and wing it?


Can you even know every transitive dependency in an average Node.js project? I just looked at a simple web service we have, which doesn't use any framework or such, and it's 5 dependencies pull in 75 dependencies altogether.

Since most applications nowadays are server side, you would usually already pull 1 GB+ of Docker layers, before you even add application + libraries.

Facebook on iOS seems to be around 400 MB of size (first result from quick googling, might be wrong), and average Electron app is 120 MB+, so I don't think the size is a huge concern.


For licensing reasons alone, almost got hit by one dependency switching from LGPL 2 to GPL 3 and one project we bought dropped dead once someone went over its dependency tree and noticed the mess of highly incompatible licenses, it would have taken years to get to a point where we could legally publish anything. Not knowing about all of your dependencies is a liability.


Not full knowledge. But you should know about every single dependency, know what they do and if they're from a trustworthy source. Being able to say with confidence that you aren't installing malware on your customers machines is the least you can do.

On the developer side there's more though, you should know what their release cycles are like, how they manage compatibility, how long they support older releases etc. You don't what your app stuck in a 3 month upgrade cycle just because a transitive dependency needed an update.

There's a reason dependencies are there own form of technical debt and need to be minimized.


Knowing every transitive dependency in your application stack is totally unrealistic and is pretty much impossible for any modern commercial software outside of specialized/embedded systems.

Having knowledge of every dependency explicitly linked into your application is a basic tenet of software development that literally every software professional would endorse as a necessary best practice, but it's not what we're talking about here. I am 100% certain that every developer with a commercial Electron app is aware that they are relying on Electron as a dependency and Github as a trustworthy software vendor.


> outside of specialized/embedded systems.

I think you're conflating platforms and dependencies. The OS it runs on is a platform that the the user already trusts, left-pad is a dependency the developers are responsible for. There's some grey area like electron or the JVM but even there electron sticks out as a huge binary blob the user isn't explicitly asked to install.


I never brought up operating systems in the context of this discussion on dependencies. Electron is not an operating system, so I am not sure what your point is.


Chromium and also Electron are trustable sources. Besides that any Mac OS X App from 10.15.1 (Catalina) has to be notarized. I got the dmg notarized so I know that the malware is not the issue. Now asking every ElectronJS developer to know every single part of Chromium or even electron itself is a bit unreasonable.


as CTO I know all the dependencies in the application stack of our company and I require developers to have sufficient understanding of their purpose, licensing model etc. There are tools to simplify this task. It’s much harder to do for TypeScript than for Java, mostly because NPM ecosystem is a huge pile of junk, but it’s still important part of developer's job.


> as CTO I know all the dependencies in the application stack of our company

You know all of the transitive dependencies in the application stack of your company? Out of curiosity, what is the ballpark figure on the total number of transitive dependencies in your application?


Hundreds, mostly because of the JS nonsense. Our Java microservices are lean and strictly controlled.


as CTO I know all the dependencies in the application stack of our company

I'm a few years out of the Java world these days, but you've vetted every line in every one of those Apache commons projects that gets pulled in? Because that's a lot of reading...

Over 10 years ago I went through every single Java RSS parsing library and all their forks (I think there were 5) to fix Xml eXternal Entity (XXE) attacks (eg[1]) and submitted fixes for them all.

That was a huge amount of work, because they all used random version of different XML parsers, all of which required external entity processing to be turned off in different ways.

None of the authors of the packages were aware of the issue, and as far I could determine at the time I was the only person in the entire Java ecosystem who knew all the different parsers arguments.

This was a critical, remotely exploitable vulnerability. I'd never claim to know about it now, and it was only for a few weeks back in 2006 that I really knew it then.

So when you say you "know" all the dependencies in your stack, what do you mean exactly?

[1] https://rometools.jira.com/browse/ROME-46


We barely have any of the Apache commons dependencies - in most cases use of them is not justified in modern Java. If there’s anything like that we are ready to support such dependency on source code level, patching and setting up own build pipeline if necessary. Free software cannot be trusted if you are not ready to own it. Commercial software cannot be trusted either, but there are other ways to manage the risks there.


I can't believe you check all the source code, dependencies source code and the rest of the shit show that npm brings to the party, that's very cool, all CTOs should be like you. As a CTO should you have to do this though? I'm not sure.


We are growing startup and it’s important to have this culture of understanding what and how you build from the very beginning. This responsibility is now transferred to technical leads, but I’m still aware of what’s going on and spend some time on the code reviews.


How much time does it take to read through the millions of lines of code?


Usually you don't write a project and then sit down to read through all dependencies, but it's a process that happens when you do add a dependency.

So, the process would be something like: have a problem that a library might solve, find a library that could solve the problem, verify it can solve the problem, look through the implementation, look through it's dependencies, then actually include it in the build. If anything doesn't look nice at each step, rollback and find something else or start writing your own implementation.

Do this from beginning of the project and you'll always have a full understanding of the system.


I do know just that for apps I ship.

I will never in a million year ship anything on, for instance, node.js, for exactly this reason.


I think that's not an unreasonable thing to expect at all. If the libraries you're using make that impossible, then you shouldn't use those libraries. You should know what you're shipping.

As a developer, I'm honestly and utterly stunned to see other developers arguing otherwise.


It's going to sound uncharitable, but if you're clearly being rejected for something that your dependencies is doing wrong you should make time to figure out which one it is.


Is it really difficult to find private API usage? Can they be searched for through static or dynamic analysis?

I don’t develop for iOS so I’m genuinely curious. Do they provide automated tools for developers to use? Or a flag that fails your build if you’re trying to call private APIs: For that matter, how are the reviewers catching these API usages?

I find it strange that a private API can be used accidentally, without something notifying the developer before they’ve gotten to the stage of submitting their app.


> I find it strange that a private API can be used accidentally, without something notifying the developer before they’ve gotten to the stage of submitting their app.

It's difficult to use private API accidentally. However, it is possible to use a dependency that purposefully uses private API, which is what happened here.

> Do they provide automated tools for developers to use?

No.

> Or a flag that fails your build if you’re trying to call private APIs

Kinda, but that doesn't help you if your dependency is trying really hard to use that API and has been precompiled.

> For that matter, how are the reviewers catching these API usages?

They're running somewhat stupid static analysis and possibly some dynamic analysis? They don't tell you what they do but they're not very good at it and don't generally catch even basic obfuscation. However, if a human finds your private API usage and you look like you're trying to obfuscate it, they won't be nearly as lenient.


Yes, as indicated in the OP you can use otool to see which private APIs are being called.


Your dependencies (including the transitive ones) are your responsibility. If you can't keep track of them, perhaps you fucked up. https://queue.acm.org/detail.cfm?id=3344149


> You may not have time to inspect every single node in the dependency graph.

You may not have time to do your job properly?

If you're using libraries in your project, it's normal and expected that you know what those libraries are doing and what those libraries depend on. You should know this stuff regardless of what Apple (or anyone else) may require.


Have you never run maven, sbt, gradle on a Java project, or PHP compose or .. anything in node? There are so. Many. Dependencies in some of the frameworks people commonly use. It can get pretty insane. We all remember left-pad, right?


Lack of knowledge of your dependency tree isn't really an excuse here. If you're submitting your application to an App Store -- where one of the express purposes is that customers know the application is safe -- then having an unknown dependency is not really a good argument.


How are you sure that your code gets compiled properly? Do you read the assembly generated for the processor and the source code for your compiler?

Are you sure that your machine code gets run properly? Do you test the CPU hardware and all the logical gates and whatnot so that they respond to the schemes and it passes the electric current properly?

Like xkcd 378, we could follow this logic quite deep. At some point you just have to trust, or at least assume that something is going to work, without properly verifying it yourself.

Smarter people than me have essentially dedicated their life to some extremely specific area of computing. It's not reasonable to assume that I could and should deep-dive into every possible nook and cranny just in order to build an application. I already have to do a whole lot of assumptions because of my hardware used for development, my OS and software tools like my IDE, task runners and yes, external libraries.


> It's not reasonable to assume that I could and should deep-dive into every possible nook and cranny just in order to build an application.

I don't think anyone is suggesting that you should.


Yeah... Everytime I try to use something like that and it wants to pull in 10 or 50 dependencies, it's a hard no. I would rather write something from scratch than use something and potentially debug through all those layers.

If it's in my product, I'm responsible for it, so it needs to be possible for me to audit it, even if I may not be looking too closely.


Because Electron developers might say "we fixed it" and the app developer might resubmit based on that and now they're banned due to a mistake made by an upstream dependency.

It's not like this app developer is intentionally using private APIs. "Resubmitting the same thing and hoping that it doesn't get caught" seems to be a strawman.


That resubmit approach ways used by at least one camera app years ago who masked their private API usage to secretly include a volume button “take photo” feature. They were told to knock it off (and Apple also added that option to the API at a later date).

Between that and the folks who hid MAME in an app or whatever, I think Apple is not simply constructing straw men when they warn that attempts to circumvent the spirit of their request - and the letter of it - will result in a lifetime ban.


Camera+ didn't use a hidden API - they just used a standard system volume control but placed it offscreen and monitored if the volume changed (and then lower it imperceptibly if you hit 100%). And Apple has still not added an API to do this officially, last I checked all third party camera apps use a similar hack.

What changed was just the interpretation of the app store rules - the rules said something like "you're not allowed to use hardware buttons in a non-standard way". Once they added the volume shutter feature to the system camera, now it's not a non-standard way and it's not against the rules.


Hence why you should audit your third-party dependencies in cases like these.


How exactly?


I would assume that a quick grep through your project for the symbols mentioned would tell you where the issue is.


it would but it wouldn't solve the problem. This would require the developer to modify electron and basically run his own branch. It would then make your package possibly acceptable (but attention here: as Apple clearly stated keeping too use private APIs can get you banned so if you miss something you can lose your access to the apple store) leaving however everyone else using electron with the same problem. So the solution has to come from Electron.


> So the solution has to come from Electron.

And until it does, developers should not use Electron.

There's a number of reasons why I refuse to use Electon-based apps, and this is one of them.


what if the function calls are generated with macros or something?


Isn't it literally the responsibility of the developer to figure it out, instead of just ignoring it because it's potentially hard?


grep the generated binary.


I suspect that most devs don't do that. I can't imagine finding the time fir that.


Who do you imagine is responsible for making sure your app doesn’t contain malware?

The only answer is that as a developer, you are responsible. Yes, we have to make calculated risks. But the buck stops at you. There is nobody else who can take responsibility for the contents of your app.


you simply notarized the app and you know that there is no malware. Also we are talking about ElectronJS and Chromium -- not exactly untreatable sources. Note that apple does check for malware and quality on the upload stage itself (now done via transporter) so it wouldn't even make it to then review state if something is dodgy.


Apple can’t magically tell that there’s no malware in an app you upload. There is no automated scan which can detect all security vulnerabilities or back doors in code. And we’re talking about electron plus hundreds to thousands of npm modules - which contain who knows what.

If you pull in some bad modules, directly or transitively, and as a result your app steals my data or worse, that’s on you for shipping malicious code to my computer. There is no one else who can be responsible for that. Not Apple. Not the user. You.


I've done that over my entire career. It's always been a requirement. To say you can't find time for it is the same as saying that you can't find time to complete development.


[flagged]


Please don't attack people like this. I'm fairly sure they're here reading the comments, and even if they weren't, you don't need to call them things.


Sometimes saying the truth is unpleasant. But the fact is, these developers have no idea what they are using, or what runs on the users' machines. They bring a ton of dependencies and have no idea what those involve. If that is not incompetency, what is?


"use or conceal"

"use"

If this was "don't conceal or we'll ban you for life", it would be somewhat understandable.

But it's "use or we'll ban you for life" which is just insane. Apple is at the height of their arrogance towards developers.


This policy has been there since the beginning of the App Store.

If you use a private API they will reject the app. If you try and hide the fact you are using private APIs after has told you to stop then they will ban you.

It's all very common sense and not arrogant at all.


> Apple is at the height of their arrogance towards developers.

Yep. I've migrated away from macOS after using it for a decade over to Linux, and the developer experience is first class.


is it possible to write a GUI app that looks native in all common desktop environments yet?


Sure, if you write the GUI portions in the native toolkit and factor out the backend into your cross-platform language of choice.


I would argue that's not really a "first-class" developer experience from the perspective of developing for Apple products on a Mac.


The "first class" experience for developing on a Mac would be to develop only for the Mac. If you're not doing that, your job is going to be a bit more difficult.


Yes, I'm aware. But it's a bit weird to say the developer experience on Linux is first-class. For things that don't have a GUI, sure. But that's not what the discussion was about.


I remember watching the linux communities response to the mono project and realizing it was sort of hopeless.


Qt works well for me, as well as Tcl/Tk.


Qt?


That won't really look native, will it? I thought Qt things looked like Qt things.


As far as my experience goes, it looks pretty native on Windows. Looking at the documentation [0] it also seems to strive for mac-OS native look and feel.

[0] https://doc.qt.io/qt-5/macos-issues.html


This is just a phrasing of a sentence in a mail. It does not define either what reasons they are allowed to ban you for, nor does it define what reasons they will use to ban you.

They are allowed to ban you for literally any reason. What matters is what they do, not the exact phrasing in a random email.

And in practice, they will ban you if you actively try to skirt their rules after they tell you to cut it out.


You assume it isn't an honest mistake. Most people submitting electron apps won't have knowledge of the browser engine layer and its calls to Apple APIs and probably will have some difficulty assessing whether or not they have resolved the issue. That doesn't make them bad people. They are not malicious or trying to hide things. Apple's scripts should give them more chances until they get it right.


Presumably you can't check for violation yourself without submitting.


You can, and the rejection email even provides instructions for how to do so.


And where will you get the current list of all forbidden functions/APIs, not just those for this specific case with Electron?


Whatever symbols are found in the public header files in the /System/Library/Frameworks. Iirc, there are tools which look at a binary's used symbols and compare them to those headers.


Of course you can! How do you think Apple's checking your binaries?


Using some internal tool.


The internal tool is very likely using/parsing otool / ldd output and similar. eg cli tooling that comes with macOS itself


No, it’s almost certainly just a search for strings and looking through the symbol table.


That would be very easy to work around with dlopen and some string obfuscation. It's probably a bit more involved.


In practice it is pretty easy to slip things past the automated checks if you try to, which is one of the reasons they threaten you with a permaban for doing so.


exactly. Apparently Apple just started now to check against these private APIs.


Huh? The problem isn't that the developer itself is trying to cover his misbehavior, but the fact that the developer can get banned for something out of his control.


The developer is the one who takes responsibility for the submission. Enforcement is meaningless if you can just say "oh I asked you to publish dangerous code, but it's not my fault."

It's the same reason people hold companies like Apple and Nike accountable for working conditions in their factories even if they hired a third party to run them. Third parties are not the ones putting their brand on the product.


There's nothing out of the developer's control about what they submit to the app store.


The developer chose to use Electron, hence the entire endeavor is in their control.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: