Let's say you have a app which uses passwords. During development, you want to troubleshoot some things, and use NSLog() to print out the password to see if it is working properly.
At a certain moment you are happy and everything is working.
You send your app to Apple and finally the app is accepted and submitted to the App store.
You forgot to remove the NSLog() which output the password....
Is there any way this can be bad? Or is there any way a hacker can listen to those NSLogs()?
Yes, this could be very bad, if your app crashes. Once users sync their device, the crash logs will make their way to their computer, along with the content of NSLog. This makes plaintext passwords available to anyone with a binary file reader.
For example, if Alice gives her phone to Bob, then Bob enters his password, completes his task, logs off, and gives Alice her phone back. Then your app crashes. Once Alice syncs her phone, she gains access to Bob's password.
Yes, this is bad. I have seen discussions in which attackers quickly asked about device console logs. Using the strings from those logs, they can quickly search the executable binary for similar strings, like the format string used for part of the log entry. Example:
NSLog(#"user entered password '%#'", passwordString)
Finding the format string, they can quickly find the part of code that actually uses that string, and thus they have found the part of code that processes passwords. They can then analyze the relevant code to bypass the password altogether or do whatever they want.
Even if the device does not hold a lot of console data for long, all an attacker might need to do is connect a stolen device to a computer, start the app and enter a random password. If the app logs the password (correct or incorrect), then the needed strings are still captured and the attack begins.
Of course, if the log line is still in the device console data, an attacker also gets the actual password for an actual user. And if that user reuses user names and passwords (as many people do) the attacker may now have the credentials to a user's other accounts on the internet, which may be more sensitive.
Many programming discussions advise against using NSLog directly and recommend using a macro like DEBUGLOG which will compile out of release builds. If that is used for debugging, then the app will not leave such clues for an attacker to use.
I guess . device log would contain that password !! this can be seen at xcode-window-device/device logs .
It depends on what kind of passwords your storing.
I believe that log files are stored on your iPhone. But I'm quite sure that reading these files without connecting the actual device to a computer is impossible.
Extra note: If I have to be honest, I wouldn't reject my app for reviewing at this moment. It's a good idea to prepare a patch and when your app is reviewed you should upload the new version as soon as possible. However if your saving passwords that connects the app to some sort of database, I would reject it.
Related
I want to implement deferred deep linking in my iOS app as a means of tracking referrals. When a user of my app wants to refer a friend, I'll generate a URL that has a unique referral code. When the other person receives the link and opens it, I want it to take them to my app's page in the App Store. Then if they install my app, when it first opens, I need a way for it to read the referral code from the original URL.
I've found may pages about deferred deep linking on the web but none that really explain how to do it. Instead, these pages all end up telling you to install some third-party code or use some commercial service. This isn't what I'm after. I want to learn how to do this myself.
There are lots of old pages out there that recommend convoluted and error-prone solutions, like tracking the user's IP address, putting the referral code into the clipboard, or somehow obtaining it from a cookie in a web view. I don't think these are the correct solutions to be using in 2022.
If anyone can recommend the appropriate resource, I'd appreciate it.
If it is the case that Apple simply doesn't want us to do this and doesn't provide any support for it, then I'd like to know that too. I was under the impression that they did, but maybe I'm wrong.
Thanks,
Frank
Apple's Universal Links allow for this (would understand the difference between the typical URL Scheme and Universal Links as threshold). This assumes you're willing to do some lifting server-side along with other hurdles on the iOS side, largely administrative.
A benefit of Universal Links and the server-side work is that you're provided a fallback webpage if a user does not have the app installed. Since the app should open if downloaded, you could typically just redirect to the app store from this URL. In this case, though, before any redirects, you could execute an operation to decode the unique params passed in the URL and persist it in a remote data store. The data encoded needs to be required and verifiably unique during your registration -- email seems ideal.
If that's feasible, your standard registration flow could require email verification with a link to the app as a mandatory entry point (think slack magic link). When the user submits his/her email to verify, you could first check that email against your data store to see if it maps to any previously decoded referrals saved from the flow above. If so, you could generate a unique link for this email to your app with params that will direct the deferred/deep link.
The good news is, I found a solution. I could construct a web page that redirects the user to the app store, but before doing so, copies some text into their clipboard (without telling them or asking them to do anything). Then later if they install my app I can get the text by pasting from the clipboard. I tested this idea and it works.
The bad news is, starting with iOS 16, Apple now asks you for permission to paste. So if you try to do this, your user will launch your app and immediately get promoted with a message asking them to allow a paste from Safari. I expect most users will deny the request and just the fact that they saw it will erode their trust in the app (I know I wouldn't trust an app that tried consume my clipboard without a direct command from me).
Is there a way to retrieve logs after a crash with codename one? I have a process that does a large data conversion and my app crashes/closes while trying to complete it, only on iPhone.
I do have premium/crash protection on, but I don't get an email from this. I'm wondering if I can look at the logs and not have them wiped by closing/re-opening the app?
Opening the app appends to the logs, you can add a "Send Logs to developer" button or hidden feature and invoke Log.sendLogAsync() to email the log to you.
If this doesn't include what you need I would also suggest including the native logging cn1lib since it might include information about the crash.
A few days ago, Apple rejected my app, indicating that it didn't have IPV6 support, however I don't need that support since my app does not require internet access.
I asked the following:
Hi, my app does not need any internet connection yet.
So, why it's required to have support to IPV6?
They said:
Thank you for your response and for your question. In order to bring your app into compliance with Guideline 2.1 it would be appropriate for your app not to crash when logging in.
end
So, why do I need that Support?
If is necessarily, how do I can do it?
Please I need help
Test your app extensively and fix the crash. Enter wrong values, don't enter anything at all, intentionally try to break your app and get it to crash. Then you will find your error and you can fix.
EDIT BASED ON COMMENT BELOW
"My app don`t need conect with external database, because I got the information inside" - in this case, no, you do not need to add IPv6 support because you are not communicating with the internet for logging in purposes.
You can keep the login given it is only going to be 2 people using the app, just resolve the crash when logging in.
To test, enter a variety of incorrect passwords and usernames to ensure that there is no crash on incorrect entries, and confirm that correct entries do not crash the app.
Original Answer
Apple indicated that because there is a login feature, they think it is trying to communicate with an external database (ie a database that is not on the device). If there is no external database, just fix the crash is what they are asking.
Based on your question, you have eluded to the app not communicating externally for logging in. While some may find this odd, it is not uncommon. An example for those wondering would be a childrens app for iPad. The iPad might be shared amongst several children and as such each child might complete different sections or features of the app so an account local to the device is a good idea if there is no cloud support.
If there is external communication, you need to handle the case for no internet access. The question has been answered extensively, however this was the first result I found:
Detect Internet Connection and display UIAlertview Swift 3
Update: Why do I need to Support the case for no internet connection?
A use case:
John has just downloaded your app. He has just walked through the steps to create an account, but he has accidentally set his device to Aeroplane Mode.
John hits the "Create Now" button but nothing is happening. There is no error or success alert appearing, the screen has not changed, he can't see a loading icon. John is confused and getting frustrated because he's certain that he has completed everything in the form.
John doesn't understand that he needs internet connectivity to successfully submit a request to create an account. John decides to delete your app from his device and leaves a bad review.
John really could have used an alert saying "You need internet connection to sign up to this app. Please check you are connected and try again". This would have made John a whole lot happier and he probably would have continued to use your app with all of it's amazing features.
More information can be found in the guidelines that Apple mentioned, and further to this, the Apple Design Principles Guide is an invaluable resource.
I hope this makes sense.
We are developing an app for IOS.
Is there anyway I can check that the "identifierForVendor" that the device sends me in it's first connection to my server is actually valid?
If there isn't a way, how can I make sure someone is not just sending POSTS to my server and so making me create Device DB Objects that don't really exist?
The only secure way I have found is:
1- Make the App ask for a Device Token to APNs
2- Send it on it's first connection to my server.
3- Check with APNs Feedback Service
4- If token is ok, create the Device DB Object and continue from there.
Apple should let you know some Device-Vendor Id in a communication between Apple and your server every time someone downloads an app.
Thank you.
The simplest solution would be to append the "identifierForVendor" with something you can identify from your app. For example, if you append an alphanumeric string that looks like this: "A1B2C3D4E5F6G7" to be "A1B2C3D4E5F6G7-fromMyApp", then there is no way for someone to know what the custom appended string is, unless they have access to your code.
Of course there are more complex solutions, if you are genuinely concerned of people going so far as to monitor traffic from your app just to find the string.
Are you aware that registering for remote notifications prompts the user if they want to allow remote notifications for the app. If they choose no, there is no token generated.
Besides, they can sniff the token off the wire. Do you plan on tracking abuse and blocking users based on their token? Do you know that some actions cause a new token to be generated, such as resetting the device?
You can generate a unique ID (UUID) or use identifierForVendor, and store it in the user's key store and use that to track by device. It's still anonymous, and resetting the device resets this, but if you're tracking abusers, you can block them and they have to reset their device to try it again. This isn't much different from an APN token. It can still be sniffed, and they can still reset it. But at least the user doesn't have to say yes to allowing remote notifications.
If you're sending any kind of token, you should use HTTPS (SSL/TLS), not to protect the user from themselves (they can still sniff the token by doing their own man in the middle attack unless you are verifying the identify of the server), but this is to protect people from malicious users on the same network. You don't want to block some innocent user because they happened to use your app on a public network and inadvertently shared their token.
Of course, if we're talking a jail-broken device, all bets are off.
I have the following issue:
I've understood how to create a secure login between an iPhone app and a WebServer (SSL,Https).
My question is after creating the session token, how do I make sure that if a hacker intercepts it, in the subsequent POST requests I receive data from the same user?
I ask this because I would have to send the session token each time a request is made right? (to be able to identify the user).
I want to prevent multiple things:
Session hijacking where someone would sniff the users token and send data instead of him (like a highscore or something)
Data injection using data that would not be normally sent from my app like a 1.000.000.000 highscore (possible score but not easily attainable).
I have been looking at:
UDID
User Agent (if it's not from the app name of my app it's not good, the hacker would actually have to guess I do this check or download my php files somehow right?)
The app is from the AppStore. If the request comes from an app that hasn't been approved by Apple it's not ok. I'm not actually sure if you can test this or not. If this works a hacker would have to actually submit an AppStore and download it to insert faulty data into my database which I hope nobody has time for.
The MAC address. Not sure if allowed by Apple. The IP doesn't work because a valid user might change IP's.
Cookies from what I've seen can be easily traced and see what data is inside them.
Maybe I'm not asking the right question here so it could actually be how can I make sure the data I receive is from the correct user and the correct application?
The purpose of SSL around your POST requests is to prevent interception by a third-party in transit. If a hacker can get to it, it means the token was either leaked on the client (rooted device), server (insecure application logging/debugging) or they broke SSL. (unlikely)
You could perform some advanced checking by capturing device UDID (apple doesn't like this) or comparing to source IP, but it is going to be a lot of effort for questionable security improvement.
Just ensure everything sensitive is in SSL and you should be ok.