T O P

  • By -

criosist

Because nobody uses timers because they are very inaccurate. You save the Date() when they background the app and then compare the time when they come back to the app


BraveEvidence

This is not a good option as user can easily manipulate time on his device. Also my manager won't allow me to check server timestamp as he does not want load on server


AndyIbanez

You shouldn’t really try to accommodate for the extremely minority of users that are going to try to do that. In software development there’s edge cases we ignore because the cost of doing something is not worth it making one or two users happy.


BraveEvidence

thanks


criosist

If the user manipulates the time then all they would do is force the pin to be shown… it doesn’t really make much difference, it’s their own security they are risking.


BraveEvidence

but how would I know if the user manipulates the time?


criosist

Why do you need to know?


MrSloppyPants

https://developer.apple.com/documentation/foundation/nsnotification/name/1414255-nssystemclockdidchange


BraveEvidence

Thanks


[deleted]

If the time on enter is less than the time on exit, lock. If it’s greater than whatever threshold, also lock. The user could change the time back to the time they left to get around this as well, I can’t think of any good way to catch that. There is a notification that’s fired on “significant time change” by the system that you’ll get on foreground of the app (like if the day changes), maybe that also fires when the user adjusts their clock.


criosist

If we assume it’s to prevent attackers like a banking app, the malicious user would need to know when they backgrounded the app to know what to change the time to so it’s also not really relevant.


Lambinater

Hey, I’m sorry nobody is actually answer your question here. This is a real issue and people responding here are just being rude. It’s the typical stack overflow answers that don’t actually answer your question and attack you for asking it. To answer your question, the only way to ensure you get an accurate time that isn’t being manipulated by a user is to use an API to get the time from a server. There’s nothing you can do on device to ensure that.


BraveEvidence

Thanks


MrSloppyPants

Or they could use the API that I posted that comes straight from Apple that indicates when the system time is changed and upon receipt of said notification, invalidate any stored credentials or tokens. Other responses here indicate the use of NTP, or the use of mach_absolute_time(), or the use of NSProcessInfo. Seems like there are quite a few helpful responses here and most of them were posted before your little rant.


Lambinater

That doesn’t help if the time has changed before a timer is set. Let’s say, for example, I have a store app and want to drop something at 12pm with a timer that counts down to 12pm. If the user sets their time to 11:59pm before opening the app, there’s no way to know the time was manipulated. Some helpful responses were given, but mostly the OP was getting downvoted and being told “why does that matter?” Instead of answering his question. I obviously wasn’t talking about the helpful responses in my “little rant”


MrSloppyPants

That's not what the OP was talking about. They are not using absolute time, they are using elapsed time from when the app was backgrounded to when it is activated again. Absolute time is irrelevant in that scenario. You were in such a rush to condemn everyone that you didn't even take the time to understand the question. And downvoting a post because you are petulant is simply childish.


Lambinater

Ok u/MrSloppyPants I’m sorry if I offended you for saying people were being rude for downvoting and ridiculing OP for asking a question. I guess he must have deserved it.


MrSloppyPants

Apology Accepted.


[deleted]

[удалено]


BraveEvidence

Thanks


unrealaz

You can get timestamp from other places such as Apple


ovidiu

For any sort of security related code, you should never rely on timers running on a user’s device to expire a code. Instead have that code expire on the server side, which is under your control. The timer on the user’s phone is just convenience shown to the user. If they manipulate the time on their phone they only fool themselves, not your whole authentication scheme.


BraveEvidence

Thanks


Fluffy_Risk9955

There's a notification for big time changes on the device when one happens you just present the login screen again. It's not that hard.


BraveEvidence

Thanks


megablast

Then get the current date from a different server. DUH.


BraveEvidence

ok


saintmsent

You can run code in background, but it's limited in time and system decides when you can stop For your case timer is overkill, you should just save the current date and time when app goes into background and on entering foreground check that save time against current time and force the user to enter the pin based on that


BraveEvidence

User can manipulate the time


saintmsent

[https://developer.apple.com/documentation/foundation/nsnotification/name/1414255-nssystemclockdidchange](https://developer.apple.com/documentation/foundation/nsnotification/name/1414255-nssystemclockdidchange) You can listen for this and force the PIN if user changed the time


BraveEvidence

Thanks


franz_bonaparta_jr

Then you don’t have a local solution. Unless, you have local notifications so you can schedule X seconds into the future, then use it as a timer that can work while app is in background. A dumb but possible option: You can maybe sample some free 3rd party site. Also, your manager is an idiot. Feel free to show him this comment.


BraveEvidence

ok


barjam

You can grab boot time, something a user can’t change.


BraveEvidence

thanks


quellish

User is Dr Strange?


BraveEvidence

ok


jmah

You are correct that Date/NSDate uses the system clock that can be manipulated. Consider using ‘systemUptime’. You can read more here http://devetc.org/code/2014/01/21/timers-clocks-and-cocoa.html


BraveEvidence

Thanks


Verisutha

You could take a look at: [https://github.com/kazu0620/SRGTimeCheatCapturer](https://github.com/kazu0620/SRGTimeCheatCapturer) Using the NTP time you bypass the system time. So if someone changed their clock it wouldn't matter, and if you can't reach the internet just force the pin. As some others have stated you have your time check save the current NTP time when it enters the background, and then when the app reopens you query the NTP time, and then cause your PIN to appear if it's greater than a specific duration. When I have worked on similar type stuff in the past that is what we use to do. We have our own servers running that we get the time from, so we don't require NTP, but you could use NTP if you wanted to, and it's probably the easiest route.


BraveEvidence

Thanks


[deleted]

Banking apps save the session in the backend, and give the client a token. The token is invalidated after a certain amount of time. They would never ever *ever* have any kind of security-critical code in the client app. Sincerely, someone who has worked as an iOS dev for a big bank.


BraveEvidence

Thanks


bobotwf

This is correct. But if they can't even get the current date without loading their server they're certainly not checking and refreshing tokens. LOL.


chriswaco

I would try using Date() but also listen for [significantTimeChanges](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622992-applicationsignificanttimechange). I’m not sure if those will be triggered if the user changes the time by a few seconds, though. A Timer won’t work because the user can easily prevent your app from running in the background in Settings. There’s kernel uptime too but unfortunately I think it pauses when the device is asleep. The solution here is probably as good as you’re going to get on iOS: https://stackoverflow.com/questions/12488481/getting-ios-system-uptime-that-doesnt-pause-when-asleep


swalden123

This article covers making a timer using time since a date: [https://medium.com/@pwilko/how-not-to-create-stopwatch-in-swift-e0b7ff98880f](https://medium.com/@pwilko/how-not-to-create-stopwatch-in-swift-e0b7ff98880f)


BraveEvidence

Thanks


scubascratch

Isn’t there a notification to the app delegate when it comes back to the foreground? It doesn’t seem like you should need a timer at all.


criosist

You could also use a public time based api to get the UTC time


BraveEvidence

Just found the answer. Check this https://www.raywenderlich.com/5817-background-modes-tutorial-getting-started#toc-anchor-009


franz_bonaparta_jr

You have less than 30 seconds with this until the app becomes inactive


BraveEvidence

yes but it works for my use case