I'm trying to figure out database security in Java. Like video games, desktop app and others that uses database in its code and how they can store their password in it.
Here's an example:
There's an application that uses MySQL database for storing users data and their information.
A user is registered and logged into our app. He has 0 coin in start. He bought 100 coin from shop and his coin data changed to 100. During the steps that I mention, he always use database for insert and update his data.
In a nutshell, how can I hide my database information (username and maybe IP?) in my Java code?
In addition, I've searched a while and found that you can send web request for information, but if anyone finds the code of request, they also can make their program and use same request as my app. So, I cannot figure this out.
Usually, the database is in a server that you controls, and you provide an API to make requests.
In these requests there's no information about database username or password, that should be on your server.
Then, you need to protect that connection. Normally, yo do that with authentication and authorization. You need to provide username and passwords to your users, and that is present in any request they do to your server. Also, you need to make controls in your server to control what can do each user (control that a user cannot perform any query they want).
A common way to do this is using federated authentication and authorization, with protocols like OAuth2.0 or OpenID.
Also, you need to make sure that you use HTTPS, or attackers could capture the traffic and extract all the request information.
Short answer: you never talk from the Front End (UI, mobile application, whatever) to the Database.
Usually Frontend talks to some backend server - an entry point to the backend word, a gateway (there is indeed such a term). From that point, the request can be routed to another server, or be processed in the same server (depending on the application, its complexity, architecture, etc) and only after that the information should be stored in the database (or queried from the database and returned back to the end user).
Only the gateway is exposed to the "outer word", all the backend services and of course the database should be protected from the accidental/malicious access at different levels:
at the level of network so that it will be physically impossible to connect to it if you're not making a connection from one of the backed servers
at the level of application security - so that it will be impossible to connect to the database without appropriate credentials (username, password, etc). Note this are not the same Username/password that the end user must know in order to login to the application, these are the data about the user, it has nothing to do with the user / password required to connect to the database.
The answer to your specific question is to use Java's "secret storage" features. This question may be a starting point.
The wider point is - please do not make a MySQL database directly accessible from the internet if that's what you're thinking. The security of such a solution would require specialist skills and your question suggests you don't have those skills...
If your application runs outside a local area network (and even if it runs inside the network), you probably want to put a central service layer in place - and API - to handle requests from your client applications. In this case, you still need authentication - you don't want to allow unauthenticated users to add, remove or spend your coins. Most API frameworks have out-of-the-box solutions for this.
Related
Let's say we have a very simple Java application, that edits resources on remote servers, that it authenticates with using Access Tokens. Application always uses the same identity, so it is always using the same client id, secret and refresh token to obtain access token.
The whole authentication process is supposed to go through without user intervention and app should perform actions automatically triggered by the user from another application. The other app is sending HTTP requests, but the whole thing would only be accessed in internal network and there would be no "legal" way to access it outside of it.
Is there a way to keep this data (refresh token, client id, secret...) securely within my application?
I have seen similar questions, but they all talked about websites and cookies, but this is supposed to happen under the hood, without any frontend etc. so I don't think those apply to my issue.
Edit: the application will be deployed on an internal server so it's not a Desktop solution. Basically there is an internal app that will send HTTP request to mine, triggering edit on a remote server that is outside of the internal network.
It is not a good idea to store client secrets, access tokens, refresh tokens etc in persistence storage unless it is stored in a secret store (like Vault). But there are other options.
If you are using Spring then you can use Spring OAuth2RestTemplate or else you can write something similar by looking at the code.
It acquires or renews an access token transparently and caches to avoid round trips to Authorization server.
The simplest option is to use memory storage, but if that diesn't work because you need to deal with restarts etc, operating systems provide per-user secure storage. This is a model sometimes used by OAuth desktop or console clients:
Credential Manager on Windows
Keychain on macOS
Passwords and Keys on Linux
It would require some native interop to interact with these credential stores, via use of a library such as java-keytar.
DESKTOP EXAMPLE
For something to compare against see these resources of mine:
Node.js desktop keytar code
This blog post has some related screenshots towards the end
I have read a lot of about the way to provide acces to a REST API and I still cannot come with a decision what to use.
In my case I am writing a REST API that will be used by the users of the mobile application(android&iOS), thus I do not provide or require access from third parties and this makes me think that I don't have to use OAuth.
However I have considerations about how to provide access of one user's account from multiple devices and how to provide offline access.
Another consideration I have is how should I restrict the API access, for example if using API Tokens what are the best practices for expiration and renewal of the tokens?
You have several topics in your question:
What are the benefits of OAuth2 for an internal API exposed on the Internet?
How should I manage tokens?
How can a user gain access via multiple devices?
How can a user have offline access?
I discuss these questions below.
Oauth2
OAuth2 offers a standardized protocol for several authentication schemes of varying complexity. One of the most complex use cases is the 'Authorization Code Grant' flow which allows a resource owner (user) to grant specific access to a client application via an intermediary, the Authorization server. This is what happens when you 'login using google'. The advantage of using OAuth2 over a homebrew solution is that the protocol is clear to all parties and less likely to contain fundamental flaws. A drawback can be that the protocol is not that flexible so some custom scenario's might be hard to support within the boundaries of OAuth2. If you don't have the immediate need for any of the typical OAuth2 scenario's (or a stakeholder demanding use of OAuth2) then I suggest not starting off with it, but to implement a simple token scheme yourself.
Managing tokens
The most common way to manage API access is by using tokens. A token is generated when the user logs in, typically with username and password over HTTPS. The token is persisted on the server and must be supplied by the app in each request. This is similar to the session ID used in web applications which is automatically generated and handled in-memory by the application container on the server and passed via a cookie or request parameter. An API token is typically handled by the security layer of the application itself, persisted in the database and passed via the 'Authorization' header.
A token should have an expiration date. One should decide on the best interval for this and whether token renewal is automatic (each time the user accesses the API) or explicit (force the user to re-enter credentials after expiration). This depends on the type of application and the level of security required. Tokens can also be revoked manually on the server.
Multiple devices
Each token can be associated with a specific user and device to allow access on multiple devices. This means each device must be uniquely identified, typically with the IMEI code. This makes it easy to revoke all tokens for a specific device or user at once.
Offline access
The typical way to offer offline access is to cache relevant data on the device. For example the Google Maps app allows you to make specific regions of the map available offline. To avoid (too) stale data you could keep track of the token's expiration date and invalidate the cached data after this date. An issue to be aware of is the handling of offline edits by the user. These edits have to be processed when the device comes online again. When simultaneous edits on the same data are encountered a strategy is needed to resolve the conflict, e.g.:
one edit overrides the other depending on the type of edit or the role of the user
the last edit is ignored or offered for resolution to the last editor
some types of edits might be 'merged' automatically
etc.
Another nice and simple strategy is to disallow all edits whilst offline.
There are 2 things you want to protect / authenticate
That the client app is authorized to use the service
That the user is authorized to access personal data
App authentication
A mobile application is an untrusted client. Even if you gave nobody access to the app source you must expect that any kind of authorization secret or mechanism is unsafe and can come from a hacked app or other malicious tool that emulates the behaviour of your apps.
For authenticating the app, all you can do is to have a client id, but not a client secret. E.g.
http://service.com/rest?client_id=android
Reply method(String client_id) {
if (!client_id in ["andoid", "ios"])
return Unauthorized();
}
You can change that schema to something a little harder to guess but anything you do boils down to the same security level.
User authentication
Protecting user data is crucial and luckily possible. The key difference is that the secret is not statically hardcoded into the app, it is only known to the user.
One "easy" way to authenticate users is to use other accounts they have. Schemas like http://openid.net/connect/faq/ allow you to do exactly that.
You basically delegate the authentication to some other service. and get a (per service) unique user id which you can use in your code as key to all user data. An attacker can not forge this since your server can authenticate that the token is valid by asking another service. Looks roughly like
http://service.com/rest?client_id=android&user_token=aasjkbn9nah9z23&user_auth_service=facebook
Reply method(String client_id, user_token, user_auth_service) {
if (!client_id in ["andoid", "ios"])
return Unauthorized();
authenticated_user_id = user_auth_service.getUserIdOrFail(user_token);
accessDatabase(authenticated_user_id);
}
An attacker can still use your service from some evil app but there is no way to access accounts he has no access to anyways.
And if you hardcode access tokens into the app, you better don't expire them or make sure to handle that case specifically in the app somehow. There are always users with outdated app versions.
Setup
We're developing a distributed application with Java and Spring where our existing client front end (complete with its own authentication, database, accounts, etc.) uses REST calls to access our new server for additional services. We want to protect these resources with Oauth.
Access should be restricted by role or account. However we don't want the user on the client side to have to worry about any additional authentication apart from the already existing account. At the same time we need to provide a means for third party applications to access some resources from the outside after going through some kind of registration against the server (which is why we're distributing in the first place).
So we have set up spring security on the server side to provide accounts that should be used to restrict access to the resources. The user should log in on the client side and then be able to access only those server resources assigned to him. We have some kind of registration process that sets up the user on the client side to be able to access the server services so any account setup I think should be done there.
So the questions are
How can I enable the client side to obtain an access token for the protected resources without the user having to log in to his server-side account?
And how do I setup the server side account without needing any user input?
My thoughts
This won't do
I'm thinking I'll have to either tell the client about a new account created on the server side for that user (but then, how would I choose and communicate a password?) or synchronize the client side account to the server, and use those credentials to authenticate the client against the server and generate access tokens. But how save can that be? Also the server has a much higher security (one way encrypted, salted passwords) on its accounts and I don't really want to compromise this by using the less save client accounts.
Maybe this will?
Maybe the way to go will be to tell the server about the client account during the first authentication, create an account on the server side, store the generated token on the client side and then authenticate the client against the server with that token for each subsequent request..? Will the server be able to log-in the client using its server-side account via that token for each request?
I'd need a special resource for that initial (2-legged?) handshake that can only be accessed from the client server, right?
Also:
Which would be better suited for the task, OAuth 1 or 2?
I'm hoping someone understands my problem and can help me sort through possible missunderstandings and knowledge gaps (I'm reading through Oauth and spring security documentations right now, so I'll update if I come up with a clearer picture and thus clearer questions of what to do)
Thanks for any help!
So our current status is to use OAuth2 mostly for reasons of simplicity. We're also sure that the flaws it might have concerning security we can cover ourselves as needed and they will most likely be addressed in the future by the implementation vendors or the IETF.
To handle the communication between REST server and REST client (both in our control) we use the formerly known as 2-legged authentication, now client credentials grant. I've asked a few questions on SO about that including
our current spring-security context setup
the client credentials flow in particular
the use of long lived tokens versus reauthentication
and how to limit REST access by HTTP method
Concerning the use of client based user accounts for authentication against the server we didn't get any further.
For now we authenticate the user against our old client web application as before and then authenticate the client against the server 2-legged. In theory this will allow any user to access any resource using the client accesstoken but for now that's okay for us so we will not investigate further down that road.
Still, should anyone have a good idea on how this might be solved we'll pick it up, just to tighten security further. So, I'll leave this question open.
My thoughts currently are along the line of registering a new client ID for each user on the authentication server with a generated secret and then synchronize those back to the client server and use those client_id / secret combinations to access resources for a user represented by the generated client_id in a client credentials flow.
For our latest application we'll store accounts on the REST server (authentication provider) and have the user login against that server and then use the token to access the REST resources as intended by the spec.
i want my company website to access from my android phone but that website can only be accessed by registered member
i have login page in that i have to enter registered email and passwrd than directly from the login page only i have to redirect to my company web url ???
Please give suggestion
Thanks in advance
Edited, to be more explicit :
How to secure and restrict access to a website ?
Restrict network access
Maybe the simpliest solution. A web site is not always available on the internet or for everybody. In fact if your website sit in some machine in your company office, make it available on the net require more effort than just let local computers access to it.
What does that mean ? You configure your firewall and your network to allow access of your server for only some IP address/port. To continue on this network only solution, you can create a VPN that include your mobile phone devices.
Include authentification and authorization management directly in the application
The first solution is a first pass. It allow you to forbidd access to most people out of your organisation. But maybe you want more, you want for exemple that only people from marketing do have access to the web site. Or maybe you want depending of the user (or user group), allow them to do differents things.
The best way to do that is to directly manage uses rights into your website. You authenticate users, and when a specific functionnality is requested your firt verify is user has credential.
If you already have an IT department, it is likely that a directory is available with all users, their password and their groups. You can base your check on the directory, avoiding the harsle to create/delete users in your application directly.
Using a proxy to secure or authenticate access
This solution is like a melt of the other ones. First you make sure sure using network restriction that your web site is only accessible using the proxy machine (so only one IP basically). Then you use a web server (like Apache HTTPD server) as a proxy, or a gateway to access the website.
Basically, when a user want to request your website, it doesn't directly ask the application that manage it, but the proxy. Because the application server is isolated in the network, it doesn't have to be secured.
The proxy allow you to fine tune the behaviour of your web site :
you can add encryption using SSL to
all data that transit from the client
to server, so no senssible data is
sent unprotected
you can compress all data that
transit to optimize the bandwidth
usage (really important for mobile
device and their not so good
internet connexion).
you can use HTTP authentification to
check user has the right to access
to the page. This can be just a
login/password check, or a client
certificate to fully secure the
connexion, allowing only device
with the certificate to be granted
access.
You can tune access per group to certain part of the site, but this is not as flexible as retrictions done directly by the web site application.
Didn't catch you very well. Do you mean that you want your company website can just be accessed by android phone for registered member? If so, I think you can check what browser type can be used in android phone, and in your website check it from http request, like "String browserType=(String)request.getHeader("User-Agent");" .
I don't know if this question has any sense, but this is what my boss want.
I work in a company with an intranet web.
In my department we have developed an application wich connects to a Bussiness Object server and executes and prints reports. This is a regular client/server app with our own user/password manintenance to log in.
My boss want to remove our password maintenance and let the users log in using the intranet password, somehow the desktop app connect the intranet (i don't know if it has a web service, but probabilly yes), makes the log in and retrieves some kind of object the Bussiness Object can use to authenticate.
Can this be done? I know the B.O. can use LDAP authentication if its well configured, so that if i can verify the intranet password and redirect the same password to B.O. it can autenticate the user by itself.
The closest I have seen/created is to use the shared secret (ITrustedPrincipal) mechanism to authenticate the user against secEnterprise without knowing the true password of the user. The only gotcha with this log in model is that the Universe Connection needs to not use the Business Objects credentials for connecting to the database.
The alternate is LDAP can be used and is fairly easy to set up as an authentication method for logging into Business Objects and auto adding users. The only caveat is that LDAP groups need to be correctly such that the Business Objects groups that the LDAP groups associate to are set up correctly.
Probably you'll have to look to some kind of "Single Sign One" ( sso ) and see if 1) your server can handle, 2) You client can implement it.