I have an app that involves messaging (and it's a big part of the app). People can text each other through the app, and every message is kept on our server, uncrypted. (We never really thought of encrypting it)
The user has to accept terms when he creates his account and it's all written there, but my question is the following :
Knowing the user supposedly read the terms, is it still legal/allowed by apple to keep all the messages on our servers? We can identify who wrote it and what is written, obviously, but the users can only read his own messaging feed. Is that ok? Or should we run a encrypt algorithm when uploading the message and decrypt it on the reciever side? Or any other relevant idea/solution?
The T&C your working with Apple are documented in iTunes Connect > Contract, Tax, Bank > iOS Paid Applications and iOS Free Applications
TINLA: They don't say anything about how to store the data of your customers (by my brief understanding)
When distributing your App thru App Store as you say have you own Privacy Policy provided. If not then the standard EULA applies. the standard also does not say anything about privacy / encryption.
Related
I know, that this question is not directly related to any coding but there are several other question on SO about the App Store and its Guidelines. So I assume, this question is OK.
There are other questions about (more or less) the same issue. However they where asked / answered several years ago and the Guidelines have been updated since then. Additionally the circumstances are always a little bit different.
I am well aware, that nobody can give me any kind of guarantee on which interpretation of the Guidelines is correct. Not even Apple could do this, since everything depends on the review staff an its current mood. However It would help a lot get to know your opinion on what is allowed and what is not. Maybe you already encountered the same problem and have some useful recommendations.
The set of facts:
A Shopping List app is offered in iOS App Store. The app offers functions to create and manage any kind of shopping list. These functions do NOT depend on any external purchase. The fee version limits the number of lists. This limit can be unlocked using an In App Purchase.
There is also a WebApp version that offers the same functions (and a little more) as the iOS version. The WebApp has a one month free trial and can then be extended using a subscription model. Subscriptions can only be ordered within the WepApp, not from within the iOS app.
Both version can be used completely independent from each other.
Additionally the apps can be connected (REST API) to sync lists between them.
Obviously there are pages/controls within the iOS App, that allows to setup the connection (enter username, password, etc.).
Obviously the WebApp has to be described in some way to the user within the iOS App.
Once the free trial ended or a subscription has expired, the sync will no longer work. In this case the user needs some kind of hint why sync is no longer available ==> There has to be information about the subscription model of the WebApp and a discription on how to renew the subscription.
The "Problem":
The current App Store Guidelines are pretty vague on wether this kind of business model is allowed or not:
3.1.1 In-App Purchase: If you want to unlock features or functionality within your app, (by way of example: subscriptions,
in-game currencies, game levels, access to premium content, or
unlocking a full version), you must use in-app purchase. Apps may not
include buttons, external links, or other calls to action that direct
customers to purchasing mechanisms other than IAP.
This paragraph is not as clear as it my appear on first sight. Unlocking functionality within your app is only allowed by using IAP. Fine, so unlocking a app feature (e.g. creation of more than 2 shopping lists) would be not allowed. But is the sync functionality I described before also covered by this? Of course there has to be functionality within the app to connect to the WebApp, but the complete sync logic is implemented on the server, not in the iOS app.
The functionality the iOS app offers is "Establish a connection to the WebApp". This functionality works independently from wether the WebApp subscription is active or not. Only the functionality of the WebApp changes depending on the subscription status (accept or deny sync requests).
So: Is it allowed to add some text like "There is a WebApp, too. Use this link to got to the WebApp. Follow this link to renew your subscription" to the WebApp or not?
Or is the part "Follow this link to renew your subscription" forbidden?
What makes the whole thing even more confusing is the following paragraph form the Guidelines:
3.1.5 Physical Goods and Services Outside of the App: If your app enables people to purchase goods or services that will be consumed
outside of the app, you must use purchase methods other than IAP to
collect those payments, such as Apple Pay or traditional credit card
entry. Apps may facilitate transmission of approved virtual currencies
(e.g. Bitcoin, DogeCoin) provided that they do so in compliance with
all state and federal laws for the territories in which the app
functions.
Does this read as "Physical Goods and physical Services" (e.g. postal delivery in contrast to digital Services) or this include all Services?
So, is the "WebApp Sync Service" covered by this paragraph and thus the usage of external payments not only allowed but necessary?
Of course I could ask these question directly to Apple. But I would never get an answer. Even if I would, this would still be no guarantee, that the review stuff shares the same interpretation of the rules. So your experience and opinion will be the best "guarantee" I will ever get.
Thank you very much!
I have a client who want their own App, and only to have it in their own shop for clients, not in the iOS App Store. I was wondering if it is possible to create an App, not to submit it to App Store, but to upload it to a website, and make it available for direct download to 50 devices?
For a situation like this they should really use the Business to Business app store.
https://developer.apple.com/programs/volume/b2b/
This will enable them to limit the availability of the app to invitation only. It allows private distribution and you can set your own pricing (can be free if appropriate). This is available with the standard developer license (not the Enterprise one).
There is no officially sanctioned way to do this, that I know of, other than Enterprise-internal, or by using the developer's (your) license, which doesn't sound like what you need.
Be careful: https://www.theiphonewiki.com/wiki/Misuse_of_enterprise_and_developer_certificates
Apple has very tight control over the platform, and specifically prevent what your client wants.
I would question why your client wants to circumvent Apple here. While it is true that Apple take 30% of the price, they also provide a lot of infrastructure and security in return. Perhaps they want to maximize profit, or their content doesn't satisfy Apple's restrictions?
Developing a web app may be an alternative. When done right these can provide similar interfaces, and access can be controlled, and Apple is out of the equation.
Failing that, you could create a separate developer account for this, and the 50 devices could be registered individually by their ID. This will not be anonymous any longer, and it will have to be renewed yearly.
Technically yes you can distribute an app outside of the App Store using the Enterprise Deployment Program.
However, according to the terms of the Enterprise Deployment Program the distribution is limited to only employees of your organization, and in your scenario you mention that they want to distribute the app to their clients.
See the full details in the Apple documentation here:
https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/DistributingEnterpriseProgramApps/DistributingEnterpriseProgramApps.html
Apple's iOS in-app purchase system has been attacked in the past by people who have tricked apps into giving them content for free. They have since improved the systems involved to try to limit this kind of thing.
I've read through the StoreKit reference documents available from Apple and I have a general idea of the workflow and the checks that need to be done, and so on. However, there may be security issues that I'm not aware of.
Can anyone provide a full list of theft-attacks that can be attempted against In-App purchase mechanisms, how developers might mistakenly allow these attacks, and what are best practices for preventing them?
These are the attacks that I am aware of, past and present:
Fake App Store
Made famous by the Russian programmer Alexey Borodin, this attack only affects apps that verify purchase receipts directly with the App Store. By modifying the DNS settings of the device, and installing forged security certificates, the verification requests are sent to a fake App Store server, which automatically returns that the purchase is valid. Unsuspecting apps will accept these verification calls and deliver the content to the user.
Commentary
After this exploit was made known in July of 2012, Apple issued updated documentation and advice for developers to ensure this kind of attack would not continue to occur. Borodin has been quoted in various web articles as stating that the "game is over" based on Apple's updated APIs and best practices guidelines.
Prevention
Apple has an entire document dedicated to this loophole here. (EDIT: Link is down, Wayback if you want...although the document covered iOS 5.1 and earlier.) The biggest point they bring up is having your app send the receipt to an external server that you own, and then having your server verify the receipt with Apple. However, if you do send the receipt directly from the app to the App Store, they recommend the following checks:
Check that the SSL certificate used to connect to the App Store server is an EV certificate.
Check that the information returned from validation matches the information in the SKPayment object.
Check that the receipt has a valid signature.
Check that new transactions have a unique transaction ID.
Fake Verification Server
If your app sends the transaction receipts to your server, which then forwards them to the App Store, one option is for the attacker to fake your verification server. By some method (altering the DNS table, changing the URL, etc.) the receipt is sent to an alternate location and a "successful verification" is returned. In this way the receipt never reaches your server and you never have a chance to check it with the App Store.
Commentary
Apparently there are a variety of apps in the Cydia store that serve to run in the background, monitor receipt traffic, and redirect it for this purpose. Source: Hussulinux Blog
Prevention
If you immediately deliver content as soon as a receipt is verified, there is no known way to prevent this kind of attack. However, take this scenario: you have a user account system managed on your own server. If the purpose of the In-App Purchase is to notify your server that a particular user account has purchased an item, and the app downloads that item from your server, you are immune to the attack. Redirecting the receipt to another server will accomplish nothing for the attacker, because your server will never mark the user account as owning an item, as it never sees the receipt.
Fake Receipts
An attacker can fake the purchase process and then send a forged receipt to your verification server. Unlike the previous attack, the receipt's outbound location is not changed, but it is replaced with an imposter. This spoofed receipt is, in fact, a valid receipt from a previous App Store transaction, and the App Store will verify it as such. By faking the purchase process and then sending a spoofed receipt to your server, the content is never actually paid for.
Commentary
Apparently there are a variety of Cydia apps that do this sort of thing. You can spot fake receipts because their product_id is totally different from anything you use in your app. Apparently the most famous spoofed id is com.zeptolab.ctrbonus.superpower1. Source: Hussulinux Blog.
Prevention
In the link where I found this attack, the blogger recommended that you unpack the receipt at your verification server (base64_decode) and check the product_id before sending the receipt to the App Store. However, in this article Apple recommends that you first send the receipt to the App Store, and then read the returned information to be certain that the receipt is valid.
(Also, correct me if I'm wrong, but Apple's recommended technique could also be used to prevent this kind of attack even if you don't have a verification server. If your app sends the receipt directly to the App Store, it could examine the contents of the JSON response to ensure it's valid. But this goes against Apple's recommended best practices of using an external verification server, so I wouldn't advocate it.)
In Closing
These are the attacks that I'm aware of, feel free to correct me if I'm wrong on any point or to put forth additional attacks and fixes.
As a note, there's this website: http://www.in-appstore.com/ which claims to allow in-app purchases for free, either on iOS 5 or with a jailbroken iOS 6 device, and is active as of July 5th, 2013. While I'm not 100% sure how they are doing it, it definitely seems to involve DNS rerouting and faked security certificates, which would imply Fake App Store or Fake Verification Server, which would additionally imply that there are still apps out there that are not secured against these attacks.
Resources
Apple iOS in-app purchase hacking
My Experiences With Verifying In-App Purchase Receipts
How to detect "IAP Crackers"?
EDIT:
Additional
It seems like one or two people have swung by here and found this post useful, and I'm glad.
There's more information that can be had on this subject, either in other posts, books, or, if you're up to it, scouring the underbelly of the internet. Here's just a couple of websites and posts and so forth that I want to look into, but haven't had a chance yet. I'll add more links later when I find interesting tidbits.
http://www.se7ensins.com/forums/threads/tut-how-to-hack-ios-games-and-apps.701845/
http://www.iapphacks.com/
A couple of immediate takeaways: don't store your player's data in a simple plist unless you want it to be edited by some teenager. People don't have to hack your IAP system if they can just give themselves gold or something similar by editing the files on the disk. Perhaps by encrypting these files, you could discourage a certain segment of attackers.
Based on the se7ensins link, it seems as though an attacker can also pry apart your binary and mess with it to achieve the same ends as editing a plist file, or even more, but this will require a slightly higher skill level. Perhaps setting up jailbreak detection would suffice to deter most people who would resort to this.
Again, this section is mostly speculation, but it may help someone. Really, the level of protection you have depends on how far a developer is willing to go (down the rabbit hole of security and encryption) to protect their bottom line.
We are a startup that provides cloud storage (www.zapdrive.com). Our iOS app was rejected, and the reason given was the clauses 11.12 of the App Store Review Guidelines, which specifically says:
"Apps offering subscriptions must do so using IAP, Apple will share the
same 70/30 revenue split with developers for these purchases, as set
forth in the Developer Program License Agreement."
Please note that we are not offering any subscription from within the App. We do not have any links or buttons in the App that take the user to any external website, whatsoever. It is a very basic app, that lets the users view their files stored in "ZapDrive". To see what the app looks like, you can see it in the Google Play Store
One thing that we see could be close to a violation of the above rule is, on the first page of the App (which is the login screen), we have a text that says:
"Don't have a ZapDrive Account? Go to www.zapdrive.com to sign up for a FREE account"
However, the above-mentioned line is just plain text, and does not "link" to the actuak website.
Also, the rejection notice says:
While your app maybe be intended to enhance the experience of your
existing subscribers, with the exception of the content specified in
Guideline 11.14, if the subscribed product is used within the app, the
subscription must be offered in the app using IAP.
Please not that we are not selling any content, or offering a subscription to any content. The users already own the content, and they copy it into their "ZapDrive". The app lets them view/stream the said content.
Although, Apple says that just because other apps are doing this, doesn't mean you can do it too. Still, a lot of other apps (DropBox, Google Drive, Box etc) offer subscriptions, but do not offer IAP.
Can someone please tell us, how are we violating the App Store Guidelines? And what can we do to make it compatible? Is it the text on the login screen that's causing this violation?
My guess is the link. Does the kindle app have a link in their app? Does Dropbox? I don't think so... Take out the link and resubmit and see what happens. Or you can ask apple for more details.
Your question is not a programming one; there's no better place to ask this than Apple themselves. All iTunesConnect rejections have a corresponding textbox you can communicate with them specifically about that rejection ticket.
I'm building an iOS app, which provides a service which our website already provides. It's a subscription based service, where all features are enabled when you're subscribed. To get people to sign up for regular payments on the app, it seems like I'll have to go through Apple's in app purchasing API, with auto-renewing subscriptions. That's fine, but the problem is the service users will purchase through the app must also be available on the site. But reading through walkthroughs and the developer guide, it looks like the only way to process transactions is through the app itself, which then can be set up to pass the info to the server. But then I'm imagining this scenario:
User purchases a subscription on the iOS app, goes back and forth between using the site and the iOS app. On the day the user is to be charged, and the days after, they're using just the website, for whatever reason. The server doesn't know they've been billed though, and so features are disabled. In order for the server to find out the user has been billed by Apple, the user has to open the app on their iphone or ipad and sync it with both Apple and my server.
Is there any way for my server to ping Apple directly and get information about the purchases made for my app for a given user? I haven't been able to find anything; the two suggested layouts, with or without server, both use the iOS app as the sole communicator with Apple, aside from having the server verify that information is valid. If it's not possible for the server to get this information first hand, what other possible solution could there be?
Try to not use Apple's built in payment system, and risk getting rejected (with the app duplicating a service that's been available for years online, do we no longer have to use their in app purchasing system anyway?)
If a user is paying through Apple, have the server give them a generous buffer between expected payment dates and when features are disabled (makes the problem happen less frequently but doesn't solve it)
When their account seems expired to the server but it doesn't expect that, email the user a message saying they have to open the app or else their account will not be credited for time purchased (seems like a strange and not really great thing to have to ask a user to do in order to use the service)
This is about all I've been able to think up so far. Anyone have any advice on these solutions, or know of others, or know who I could talk to to try and figure this out?
Yes, you can check on the status of a user's account from your server. There are a few caveats:
First and foremost, Auto-Renewing Subscriptions are reserved for periodicals such as magazines and newspapers. If your app doesn't resemble those, Apple may reject it (as they did mine) and request that you use Non-Renewing Subscriptions (read: Manually-Renewing Subscriptions).
Second: This scenario would require you to store all receipts that you receive on the app, on your server.
Finally: I don't know how your username/password system works, but the user would have to login with the same credentials on your app as they do on your website.
Here's how you check the status of a user's account: Store at least one receipt per user on your server. When you want to check the status, follow Apple's procedure for Verifying App Store Receipts. Send them that one receipt and they'll respond with the latest receipt and the expiration date. Now you'll know, at any given moment, if a person's account is current or not.