REST API. Should I double-check phone verification code when sign up - rest

I have a REST Api with following path for user to register:
send verification code (/phone-code) -> 2. verify code (/verify) -> 3. enter personal information and register (/sign-up).
On the second step I mark phone as validated if entered code is correct and on the third step i check if phone is marked as validated. But imagine one person verifies the phone and another (let's say a hacker) tries to skip first 2 steps and triggers /sign-up with first person's phone. As the phone is already validated, a hacker registers successfully.
So the question is how to make /sign-up safe? One idea that comes to my mind is double-check code on the second and the third steps. But that comes with a coast of increasing the duration of validation code which is not very safe. Could you advise me something better?

Use some kind of session system on your service that uses cookies. When you sign up and verify, you remember the phone number and whether it was verified in the session.
You shouldn't have to ask for the phone number again, because the phone number should be known and in the session.

Related

AWS amplify (cognito) - change phone number during signup and verification

I have the "happy path" of signing up a user implemented using Flutter & AWS Amplify. I have made the user to verify their account using their phone numbers so that the verification code is sent to the phone and the signup process is completed.
I realised that, during testing, one could easily make a mistake. So I want the user to be able to go back and change the phone number so that the verification code is sent to the correct one. However, using Amplify, you cannot change the details if the user is not signed in, and the user cannot be signed in unless their account is "confirmed". Of course, their account cannot be "confirmed" if they don't receive the verification code and with the wrong phone number due to their mistake, they will never receive the verification code...
Has anyone faced the same problem and could help me how to solve this please?
I read that you could use Lambda functions to "auto-confirm" the account without any verification which means they can sign in, which would allow me to change their phone number if they have entered a wrong phone number. But I am not sure if this is the easiest way to do it

AWS Lambda & Cognito - Updating user phone number attribute without sending an SMS

I am working on an iOS app using Amazon Web Services and I am setting up a user data base using the Cognito Userpool. During the sign up process, if a user enters the wrong phone number by mistake and in result isn't receiving a verification code, I am trying to allow them to then enter a new phone number, and update their phone number user attribute. Right now I am using a Lambda function which uses the AdminUpdateUserAttribute function, which is then connected to a APIGateway which allows me to run it from XCode. The function itself works and it successfully updates the phone number attribute.
Problem
The problem that I am running into though, is that after the phone number attribute has been updated with the Lambda function, a verification code is automatically sent to the newly updated phone number via SMS. The verification code is weird though because when I use that code to confirm the user, it doesn't work. Meaning that code is invalid for confirmation purposes. But if I use the Resend Confirmation Code function it will then send a valid confirmation code to the newly updated phone number.
Question
So I guess the questions I have are:
How can I prevent the automatic SMS from sending after I update the user's phone number attribute?
Or, is there a way I can use the verification code that is automatically sent as a confirmation code?
Thank you in advanced.

TOTP authentication of the OTP received in my mail

I am building a Java web application with TOTP getting generated(using TOTP Algorithm) and sent via mail. How would I authenticate it?
With my extensive research,I could find all the papers showed mobile devices authentication(Google Authenticator etc. ), my application is not using mobile device in any case, just a simple OTP authentication( received in user mail id)
OTP generate function goes like this:
OTP.generate("" + key, "" + System.currentTimeMillis(), 6, "totp")
See the RFC, then you know how to verify the Otp value.
https://www.rfc-editor.org/rfc/rfc6238
If you send the OTP value via email the server can just save and remember the value it sent.
Or when the user enters the OTP value, you can recalculate the value based on the key.
If you only send values via email, than you could also send any random string.
But maybe you want to do a more common approach - why not allow Google Authenticator and Hardware tokens with TOTP?
But if you are building a web application, maybe you would like a more generic solution in the background. privacyIDEA is an open source solution, that has all this right from the start. TOTP with Google Auth, hardware token or OTP via Email and SMS. No need to reinvent the wheel.
TOTP is useful when the Code Generator (typically a mobile or desktop app such as Google Authenticator) and the Code Validator (the authentication server) are two different entities.
In your case the application acts a both the Code Generator and the Code Validator so I would use a different approach in this case. Have you looked at HOTP? TOTP is in fact based on HOTP, the difference is that while the later uses an explicit counter as the moving factor (i.e. event-based moving factor), TOTP's moving factor constantly changes based on the time passed since an epoch. (i.e. time-based moving factor).
A problem you may run into with sending time based OTP codes via email is the potential lag between the code being sent, and the code being received. Given the OTP code has to be entered within a short period of time if this lag is too large then the code will not be usable.

Password/Authentication for users inside App on iOS

my goal is to give my customers an option to lock their App's Data, so when they give their iPad/iPhone to someone else for an extended period of time, users can't access or accidentally look at confidential data.
[Some Background: It's a medical Application where physicians/staff-members would give iPads to patients. Now the patients are supposed to access some contents, yet shouldn't be able to look at other patients data]
So far, I have a password inside my App. But when a staff-member forgets and wants to reset it, the only thing I can do is "deletion of the whole database". I have a Disclaimer telling people to store their password somewhere, but this is still not the optimal user experience.
Is there anyway I could authenticate the user via his Apple-Password? This way only the person knowing the Devices-Account password can access the data and can always reset the Apple-Password with Apple.
PS: Server-Solutions, like having a User-Password pair with reset-via-mail on a server of mine is out of the question, since it would add to much complexity for the users and in many medical situations the Device shouldn't have access to the web.
Multiple thoughts:
I am not aware of any native public API to authentication using Apple password.
If your app is enterprise app, possibly you can use native private API. I would recommend to disassemble AppStore and check how does it do authentication then
You can also to try to access to some Apple web page which requires authentication and pass to it apple account and password and see what it will return. If it authenticated correctly, then you are fine and you can reset a password.
To make it secure, you will need to ask a user to enter it for a first time, so you can encrypt your encryption keys using authentication material (so you can decrypt encryption key later on).
However, I am not very big fan of this solution, since you can change Apple password and you will be stuck in such case.
Server solution is the best option and it's not that complex. Another option is Forgot password. You ask something what administrator know ("What is your first pet?") and he enters the answer when your application is configured and this answer could be used later to unlock your app.
P.S. And the best solution at the end (which is absolutely shameless self advertisement). A startup which I am part of (SpydrSafe) works on the product which solves exactly your problem. In fact, healthcare is one of the verticals which whom we actively works. If you are interested, contact me (my email is in profile)
if you authenticate the user via apple password, and they forget their apple password, then in order for them to retrieve that password is by reset-via-email .... so either way you are stuck with that dilemma.
As for actually using your apple password, no.
Best way to get what you want is to have the password stored somewhere in real life. Like another computer that the doctors can report to and ask for passwords or just don't forget the password.

iphone app - preventing spam

I've developed an app that allows users to upload some photos and share them on Facebook/Dropbox/Twitter etc. Recently it went live in the app store.
However, I'm having a problem now: a bot is creating accounts and uploading many photos on my server. I've temporarily disabled the app, but now I'm looking for an efficient way to prevent this bot from doing this.
The bot's ip address is changing very often so it's impossible to block the ip. He creates accounts with a very realistic name and email address so it's hard to find out which users are real and which are created by the bot.
I was thinking of using a captcha, but I'm not sure if my app will be rejected by Apple if I implement this. I'm preferably looking for a way so I can prevent him from doing his work and so I don't have to resend the app to Apple again.
Could anyone give me some advice on what I could possibly do?
Thanks!
This is how I solved a similar problem:
I implemented a token-generator, which generates a one-time token for every single data transfer with the server, so even one for login-data, sending a file etc. This token is generated by a secret algorithm and can be verified server side, since you know how you generate one.
After one token is used, put it in a temporary list for the next X minutes/hours/days (depending on how many data transfers your server can handle). When a user tries to send data with a used token (i.e. the token matches one in the "banned" list), you can be sure that someone's trying to spam you -> mark the account as "spammer" and decide what you wish to do.
The algorithm must produce a different token each time (the best way would be a one-way hash), but you have to assure specific "properties", with which you can proof its authenticity.
So one very simple example:
Your algorithm in the client is generating a number between 1000000000000000000000 and 99999999999999999999999, this number is then multiplied with 12456564 and incremented by 20349.
The server becomes a specific command and data, and the generated token. Now it checks, whether (number - 20349)%12456564 is 0. If it's 0, it was likely generated by your "secret" algorithm.
It's a very basic example but you get the idea…