Maintain secure session using PhoneGap - security

I have a simple jQuery mobile PhoneGap application which uses ajax call to server to authenticate a users credentials against servers db (uses CORS).
Once user is authenticated I setup some local storage variables for the session but I suspect this is not a secure method of maintaining state.
I'm wondering if there is a better & more secure way to keep track of the users session state. At the moment I'm thinking of implementing some kind of token based handshake between the app & the server for each subsequent server call post logon. I'm hoping there is a better more standard way to implement secure sessions in PhoneGap.

I think you shouldn't save origin credentials in local storage. At first, you should encrypt credentials by your encrypt algorithms and you can save it in local storage or preference(Android/iOS - best is store in preference) or anywhere you want. If another person get credentials, it have been encrypt, they not use it to authenticate with server(Only you had decrypt algorithms).
Continue, you must do something to prevent other person decompile your app. They will have your decrypt algorithms and use it to decrypt credentials-->origin credentials-->post to server success.
Have many way to secure your app, you can search and research.
Code demo in Android:
SharedPreferences sharedPref = getSharedPreferences("account", Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
user = your_encrypt(username);
pass = your_encrypt(password);
//encrypt and save account
editor.putString("username", user);
editor.putString("password", pass);
editor.commit();
//get account
String u = sharedPref.getString("username", "");
String p = sharedPref.getString("password", "");
//decrypt username/pass
username = your_decrypt(u);
password = your_decrypt(p);

Related

Where to store access token securely in UWP application?

Local storage is not right place to store tokens. But this blog post says LocalCache is generally the right location. If I store in LocalCache using DPAPI, Does this enough secure?
Does PasswordVault is good place to store it?
How can I store token securely so that outside this application token is not accessible?
I would definitely recommend storing confidential information like an Access Token in the PasswordVault as LocalSettings are not encrypted and are accessible quite easily from the app's package folder in AppData.
Although PasswordVault has a bit odd API, you can still easily use it to store the token:
var passwordVault = new PasswordVault();
passwordVault.Add(new PasswordCredential("Resource", "UserName", accessToken));
In your case, you most likely care only about the access token, so the "resource" and "user name" may be just arbitrary constants. Retrieving the token is easy as well:
//find credentials in the store
PasswordCredential? credential = null;
try
{
// Try to get an existing credential from the vault.
credential = _passwordVault.Retrieve("Resource", "UserName");
}
catch (Exception)
{
// When there is no matching resource an error occurs, which we ignore.
}
credential?.RetrievePassword();
return credential?.Password;
Note the use of try..catch. This is because the vault throws if given resource/user name combo is not found (which could even happen when user manually deletes the entry in system Credential Manager.
Another advantage of PasswordVault is that credentials are synced across devices (although this feature may be going away in future versions).
Where to store access token securely in UWP application?
In general, we often store access token with ApplicationData.LocalSettings class that place settings container in the local app data store. You could use it like the following.
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
// Create a simple setting.
localSettings.Values["accesstoken"] = token;
// Read data from a simple setting.
Object value = localSettings.Values["accesstoken"];
if (value == null)
{
// No data.
}
else
{
// Access data in value.
}
And if you want to store access token securely. The Windows Runtime provides the PasswordVault class to securely store credentials. for more please refer this document.

.NET Gmail OAuth2 for multiple users

We are building a solution that will need to access our customers Gmail accounts to read/send mail. On account signup, we'd have a pop-up for our customer to do Gmail auth page and then a backend process to periodically read their emails.
The documentation doesn't seem to cover this use case. For example https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth says that client tokens should be stored in client_secrets.json - what if we have 1000s of clients, what then?
Service accounts are for non-user info, but rather application data. Also, if I use the GoogleWebAuthorizationBroker and the user has deleted access or the tokens have expired, I don't want my backend server app to pop open a web brower, as this seems to do.
I would imagine I could use IMAP/SMTP accomplish this, but I don't think it's a good idea to store those credentials in my db, nor do I think Google wants this either.
Is there a reference on how this can be accomplished?
I have this same situation. We are planning a feature where the user is approving access to send email on their behalf, but the actual sending of the messages is executed by a non-interactive process (scheduled task running on an application server).
I think the ultimate answer is a customized IAuthorizationCodeFlow that only supports access with an existing token, and will not execute the authorization process. I would probably have the flow simulate the response that occurs when a user clicks the Deny button on an interactive flow. That is, any need to get an authorization token will simply return a "denied" AuthorizationResult.
My project is still in the R&D phase, and I am not even doing a proof of concept yet. I am offering this answer in the hope that it helps somebody else develop a concrete solution.
While #hurcane's answer more than likely is correct (haven't tried it out), this is what I got working over the past few days. I really didn't want to have to de/serialize data from the file to get this working, so I kinda mashed up this solution
Web app to get customer approval
Using AuthorizationCodeMvcApp from Google.Apis.Auth.OAuth2.Mvc and documentation
Store resulting access & refresh tokens in DB
Use AE.Net.Mail to do initial IMAP access with access token
Backend also uses AE.Net.Mail to access
If token has expired, then use refresh token to get new access token.
I've not done the sending part, but I presume SMTP will work similarly.
The code is based on SO & blog posts:
t = EF object containing token info
ic = new ImapClient("imap.gmail.com", t.EmailAddress, t.AccessToken, AuthMethods.SaslOAuth, 993, true);
To get an updated Access token (needs error handling) (uses the same API as step #1 above)
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["refresh_token"] = refresh;
data["client_id"] = "(Web app OAuth id)";
data["client_secret"] = "(Web app OAuth secret)";
data["grant_type"] = "refresh_token";
var response = wb.UploadValues(#"https://accounts.google.com/o/oauth2/token", "POST", data);
string Tokens = System.Text.Encoding.UTF8.GetString(response);
var token = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Tokens);
at = token.access_token;
return at;
}

Shiro: where credential should be stored?

Little prehistory:
I develop RESTful services. That services receives requests from the web frontend and resends it to another server with the actual business logic. I use Shiro to protect my services. Problem is that some business logic functions require a user password. Of course, I can store password in my principal, but I think it is not correct to store credentials there.
Question
So, what is the conceptual right place where I should store credentials to have access inside my REST services?
Update
Ok, I can also store passwords in Shiro sessions, but i don't think that it is the correct place.
Normally, the info is kept in an implementation of AuthenticationToken. This interface has two method: getPrincipal (for example login or email) and getCredentials(). The last is usually used to store a password.
If you look at class UsernamePasswordToken, which is an implementation of this interface, you see that the two are indeed used for username and password.
Now what we did is extend the class AuthorizingRealm for our own authentication mechanism and in the authentication method we store the token in the principal.
#Override
public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
... authentication logic
SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(login, realmName);
principalCollection.add(token, realmName);
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principalCollection, login.getPasswordHash());
return simpleAuthenticationInfo;
}
Now you can get the token later:
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
AuthenticationToken token = principals.oneByType(AuthenticationToken.class);

Automatic login with HttpServletRequest and LDAP

I have a JSF web application that uses cookies for automatic authentication without prompting for username & password. It uses a cookie with username and a random UUID, and uses a WebFilter for redirection.
When there are no cookies on the client side, the authentication is done through HttpServletRequest #login(String username, String password). Behind the scenes, this approach uses JAAS authentication, and uses a LDAP server behind.
My problem comes when my application recognizes the user through the cookies holding the userid and the UUID. In this situation,
the application doesn't know the password, so the method HttpServletRequest #login(String username, String password) cannot be used.
Should I ask the password to the LDAP server through JNDI? This doesn't seem to be possible at a first glance
Alternatively, I could store the password in my db. But this would mean duplication of information, and I don't like it.
I have seen around people simply setting the attribute "role" to the session, but this doesn't seem to be equivalent to a JAAS login. With "equivalent" I mean being able to use isUserInRole() and getUserPrincipal() methods.
So, the question is: how am I supposed to log in the user in this case? I hope that the question is clearer now.
EDIT
In order to let the code speak, I add a simplified version of the Managed Bean:
#ManagedBean
#SessionScoped
public class loginBean() {
private String username = null;
private String password = null;
private UUID uuid = null;
private boolean rememberMe = false;
public void doLogin() {
checkCookies(); // this method sets the property values after checking if
// username & uuid match the ones saved previously
if (username != null && uuid != null && rememberMe) {
// authenticate automatically. Here I don't know how to proceed, because
// I don't have the password, unless I have saved it in the application's db,
// duplicating it because it's already in LDAP server.
} else {
httpServletRequest.login(username, password); // this uses LDAP behind JAAS
createCookies(); // this method also saves username & uuid in the app's db
}
}
To do an actual container login in a custom way (in your case via an cookie and UUID instead of the password), you need to create your own login module.
The dedicated API in Java EE for this is JASPI/JASPIC (people can never quite agree on the name, complicating eg google queries).
A login module is in full control and does not have to authenticate with the ldap server (if your app can locally verify with 100% certainty that the cookie is valid). You probably do have to authorize the user (ask the ldap server for the roles/groups the user has).
As an alternative to JASPI/JASPIC you can also look at the proprietary login module mechanism that your server is using.
Using an LDAP entry for this case is equivalent to requesting that the directory server authenticate a connection using information provided by the application. In terms of LDAP, authenticate means that an existing LDAP session, that is, a connection to a directory server, has had its authentication state changed by a successful BIND request.
The web application should request appropriate information from the user to be authenticated and present this information to the directory server as a BIND request. The information required varies according to the authentication method used by the web application (LDAP client):
A simple BIND request requires a distinguished name and a password. This distinguished name and password should be transmitted to the directory server as a simple BIND request over a secure connection.
A SASL BIND request using a predefined SASL mechanism. The mechanisms vary per server and range from GSSAPI to PLAIN.
Upon receipt of the BIND request, the directory server will immediately change the authentication state of the connection to anonymous and process the BIND request. If the request can be successfully processed, the directory server responds to the LDAP with a BIND response including an integer result code of zero (0). This indicates that the distinguished name or username was able to successfully authenticate.
The web application should use some mechanism to maintain an authentication state and issue a BIND request to the directory server when the authentication state changes. This could be a session timeout, or some other mechanism. The method that is chosen should not be changeable by the user.
In summary, use the directory server to check authentication credentials and use the session framework to manage authentication state.
Edit:
Seems this was a controversial answer.
Using cookies does not handle the case of the browser having cookies disabled, and cookies are not necessary to maintain an authentication state when using sessions.
The session does not need the password, nor should it store any sensitive information like passwords in memory or sessions. The application should request the password when the authentication state expires (if ever) or the session expires (if ever).

keep your login creadianls works after close of the app and the system in universal apps

I have developped a windows store app with C#,and I want to make my application keeps the login crediantials after the close of the application (like the Groove app after connexion and the close of the App,when I reopen it in an other time I get the application interface without putting login crediantials every time)
any explication in how to do that in universal apps please
thanks for help
Here's the solution to all your problems: https://msdn.microsoft.com/library/windows/apps/br227081
PasswordVault is the perfect place and the secure way to store your user credentials. It use the Windows Credential Manager and it allows you also to roam the credentials across devices, if this is the behavior you want to achieve.
Sample code:
// Create a new credentials set
var passwordCredential = new PasswordCredential("MyAppName", "username", "password");
// Stores the PasswordCredential in the PasswordVault
var passwordVault = new PasswordVault();
passwordVault.Add(passwordCredential);
// To later retrieve the credentials
var credentials = passwordVault.Retrieve("MyAppName", "username");
// To populate the Password property in the PasswordCredential
credentials.RetrievePassword();
it's a very common scenario.
You must use Storage folder to save all the data.
I recommend you save your file in json, serialize and Deserialize the data.
with this approach you can save the credentials of the user and when the user will open the app again you will need to check if there is a previous saved data( the login credentials) if yes you can skip the login page and navigate to the main page
https://msdn.microsoft.com/en-us/windows/uwp/files/quickstart-reading-and-writing-files

Resources