We are developing an iOS application and server where a user will be able to store some personal information and top up money.
I have been reading about the OAuth Authorization flow using PKCE and seems to be the right thing to do. Still from the user experience point of view I don't like that the iOS app needs to use an external user agent to get the authorization code.
I would like to receive feedback about concretely two points.
Issue 1 - Avoid using a browser at all.
This seems to be what almost every app out there is doing. Checking Facebook, Instagram, Connect and other applications, I am never redirected to a browser to authenticate myself. What is the deal here?
My idea would be to perform a normal REST GET call and catch the Authorization Code in the HTTP redirect response.
The user's browser is the recommended external user agent. Embedded user agents must not be used for authorization requests. Authorization servers may detect and block requests from embedded user agents, as they are unsafe for third parties, such as the authorization server itself. The reason for this is because the app can then access not only the OAuth authorization grant, but also the user's full authentication credentials. The app could then potentially record or use this information maliciously. In addition, embedded user agents don't share authentication state with other apps or the browser and therefore disabling single sign-on benefits.
So the bigger security risk seems to be that the app has direct access to the user credentials.
To mitigate this issue with our iOS apps, my idea was to hash it as soon as the user wants to log in, or even when the user types it in a text field. A good answer about this is described at: https://stackoverflow.com/questions/3391242/should-i-hash-the-password-before-sending-it-to-the-server-side
Still an attacker could catch the hashed PIN. In any case: Which are the real world scenarios where an attacker has access to the mobile device of a victim exactly at the point in time where the user is performing a login?
Issue 2 - Keeping the Access Token safe.
Once an app receives the access and refresh token there is no way to fully protect those tokens from external attackers.
My idea here is to make the BE expose two API scopes:
- API Scope 1 - Provides READ access to the user's resources only. This API can be accessed using the Access Token. If an attacker manages to get the access token there is no "WRITE" damage they can do to the user's resources.
- API Scope 2 - Provides WRITE access to the user's resources, for example top up money. For this use case the Access Token is also needed, but the POST request will be signed using Asymmetric PKI. The public key would be sent to the BE during user's registration. Since the signing operations would happen in the device's Secure Enclave (2FA), it would be very hard for an attacker to make the user top up money or any other "WRITE" request.
How does this structure looks like? Thank you.