Do’s | Dont’s |
---|---|
Perform Authentication on the Server Side. (The client side should never be trusted). |
Use the Fingerprint Scanner solely for Authentication. (Possible False Positives [1]). |
Use Randomly Generated access tokens instead of sending user credentials in requests. (At worst, a temporary session token can therefore only be stolen). |
Use Pattern Locks for Authentication. (Lack of Entropy, Vulnerable to Smudge Attacks [2]). |
A password policy is enforced at the remote endpoint. (Prevent easily guessable passwords from being used). |
Use a short Pin code solely authentication. (Easily brute forced and the end user may reuse the device security pin). |
Sessions are terminated at the remote endpoint after a predefined time. (Sessions token lifetimes should be kept short to limit the attack window if an valid session token is stolen). |
Do not use any values for authenticating a user like device identifiers or geo-location. (These can be spoofed easily). |
Temporarily lock out a user after a number of failed login attempts. (Prevent an endless brute force attack). |
Avoid relying on any roles or permission information that comes from the mobile device itself. (The client side and user input should not be trusted). |
Use contextual anomaly based detection to take into account the users IP, geographic location, time of day as part of the authentication phase. (Helps detect unusual login activity). |
Log user related information. (Personal information data leak) |
A second factor of authentication exists and is enforced. (Extra layer of protection in case another authentication factor has been compromised). |
Use OAuth1.0. (OAuth1.0 has been found to be vulnerable to session fixation. Use OAuth 1.0a or OAuth 2.0 instead). |
Step-up authentication is used for carrying out sensitive actions in an application. (Useful when a user’s device is stolen and they have already authenticated through the app). |
|
Allow the user to see their current login sessions and allow them to logout of other sessions via the app. (The end user will be able to detect rogue sessions with the most accuracy instead of using anomaly detection). |
|
Perform local integrity checks within the code to detect any unauthorized code changes before doing offline authentication. (Tampering may allow authentication bypasses). |
|
Where offline access to data is needed, perform an account/application lockout and/or application data wipe after X number of invalid password attempts. (Wipe application data when a threat is imminent). |
|
Perform a check at the start of each activity/screen to see if the user is in a logged in state and if not, switch to the login state. (A session could expire during use or over time. Also check that the user has a role that allows them to access to certain app view). |
|
When an application’s session is timed out, the application should discard and clear all memory associated with the user data, and any master keys used to decrypt the data. (Prevent data leakage after the user is no longer in an active session with the server). |
|
Store a masked user identifier instead of the actual username, and replace the user identifier value in authentication with a hash value. (If a username/id is being used in the mobile app for identification purposes only (not for display in the UI), then consider sending a related mapped token to the mobile device instead.). |
|
Implement Secure Password Recovery Mechanism. (To allow a user to recover their account using security questions only they should know the answers too and sending a recovery code using a side channel such as SMS). |
|
Fail authentication with a Generic Error. (The login screen should not show hints on the existence of a username/email address etc). |
-
The probability of a random person unlocking a given iPhone with Touch ID is 1 in 50,000. Apple Support
-
Penn State researchers managed to identify the pass code patterns on two smartphones, 68% of the time, using photographs taken under different lighting conditions, and camera positions. Smudge Attacks on Smartphone Touch Screens
An Authentication & Session Management implementation has been provided in our Mobile Security Android Template App.
The Application uses OpenID Connect for authentication and access control. The Open Source Identity and Access Management server, Keycloak, is being used as an Identity Provider. The Aerogear Auth SDK is being used for communicating with the Keycloak server.
The Keycloak server is enforcing a number of Security Controls on the mobile app.
-
Brute force detection on the login screen.
-
Account lockouts for failed login attempts.
-
2FA for mobile users.
-
Session management for mobile users.
-
Audit tracing of auth events.
The main code logic is found under mobile-security-android-template/…/authentication.
The following code snippets below describe the main authentication code logic in the mobile app.
The Keycloak configuration is saved in the mobile-services.json file.
link:https://raw.githubusercontent.com/aerogear/android-showcase-template/master/app/src/main/assets/mobile-services.json[role=include]
The redirect url of the application is defined in android.defaultConfig.manifestPlaceholders
of the apps build.gradle file.
You will also need to define the URL in the SecureApplicationModule.
link:https://raw.githubusercontent.com/aerogear/android-showcase-template/master/app/src/main/java/com/aerogear/androidshowcase/di/SecureApplicationModule.java[role=include]
We can then perform the auth request and create a new intent which will handle the auth response from the system browser. The authentication phase will occur in a system browser in a safe context outside of the application.
link:https://raw.githubusercontent.com/aerogear/android-showcase-template/master/app/src/main/java/com/aerogear/androidshowcase/features/authentication/providers/KeycloakAuthenticateProviderImpl.java[role=include]
Once the Authentication phase has ended, the user will be redirected back to the mobile app from the system browser. A check is performed in the MainActivity for incoming intents so the result can be handled by the authentication service.
link:https://raw.githubusercontent.com/aerogear/android-showcase-template/master/app/src/main/java/com/aerogear/androidshowcase/MainActivity.java[role=include]
To logout of the application, we must make a call to the logout endpoint on the OpenID Connect provider along with providing the identity token and a redirect URI.
link:https://raw.githubusercontent.com/aerogear/android-showcase-template/master/app/src/main/java/com/aerogear/androidshowcase/features/authentication/providers/KeycloakAuthenticateProviderImpl.java[role=include]
An Authentication & Session Management implementation has been provided in our Mobile Security iOS Template App.
The Application uses OpenID Connect for authentication and access control. The Open Source Identity and Access Management server, Keycloak, is being used as an Identity Provider. The Aerogear Auth SDK is being used to communicate with the Keycloak server.
The Keycloak server config is defined in the mobile-services.json file.
link:https://raw.githubusercontent.com/aerogear/ios-showcase-template/master/secure-ios-app/mobile-services.json[role=include]
The startAuth()
function handles the user authentication browser flow and the back-channel token exchange.
link:https://raw.githubusercontent.com/aerogear/ios-showcase-template/master/secure-ios-app/authentication/AuthenticationInteractor.swift[role=include]
The resolveCurrentUser()
returns the user profile, which can be used to retrieve user information and the auth tokens.
link:https://raw.githubusercontent.com/aerogear/ios-showcase-template/master/secure-ios-app/accesscontrol/AccessControlBuilder.swift[role=include]
The following information can be retrieved from an authenticated user:
// Get the users username
let username = currentUser.userName
// Get the users first name
let firstName = currentUser.firstName
// Get the users last name
let lastName = currentUser.lastName
// Get the users full name
let fullName = currentUser.fullName
// Get the users email address
let emailAddress = currentUser.email
// Get the users access token
let accessToken = currentUser.accessToken
// Get the users identity token
let identityToken = currentUser.identityToken
Access Control is carried out by checking the access roles of the authenticated user.
link:https://raw.githubusercontent.com/aerogear/ios-showcase-template/master/secure-ios-app/accesscontrol/AccessControlViewController.swift[role=include]
The logout()
function is used to logout the user from the Keycloak server. The local auth tokens are also deleted.
link:https://raw.githubusercontent.com/aerogear/ios-showcase-template/master/secure-ios-app/authentication/AuthenticationInteractor.swift[role=include]
The Keycloak JS library is being used to perform the OpenID Connect based authentication.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/app/main.ts[role=include]
The OpenID Connect Configuration can be found in the /config/keycloak.json file.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/c24297cda240efa40aca292e7d0657d7432d1eba/src/config/keycloak.json[role=include]
The Keycloak JS adapter is initialised with the check-sso
config to automatically detect and authenticate the user if there is a valid session on app resume.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
The access token can be retrieved using the getToken()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
The user can logout using the logout()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
The user can be redirected to the login screen using the login()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
The authentication state can ve cleared using the clearToken()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
The end users realm level roles can be retrieved using the getRealmRoles()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
You can perform a check to see if the user has a given role using the hasRealmRole()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
Information about the authentication server can be carried out using the getConfiguration()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
The user can be redirected to the Keycloak account management screen using the accountManagement()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
The users profile data can be retrieved using the loadUserProfile()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]
You can check if the user is authenticated using the isAuthenticated()
function.
link:https://raw.githubusercontent.com/feedhenry/mobile-security-cordova-template/master/src/services/auth.service.ts[role=include]