We have an application with a script that create a conceptual model and a login role in a PostgreSQL database.
This login role will be used by the application for everything, independent of the logged application user.
How can we protect this login role password inside the application code?
Consider using a yaml file to store your credentials or alternatively place them in a .pgpass file.
The main three authentication mechanisms you could use, roughly in order of popularity, are:
Password. Here you somehow load a password in your application, and use it whenever you connect to the database. One easy way to store the password is in a text file protected by filesystem permissions (similar to how you protect SSH private keys).
LDAP. This requires an LDAP server on your network, but that is commonplace in corporate environments. It also requires loading a password in your application. The difference from the regular password mechanism is that the database server doesn't store the credentials or verify the password directly--it delegates these to the LDAP server.
Kerberos. This requires a Kerberos server on your network. Here, the application does not need to load a password; instead the user (or service account) which will run the application must first authenticate using Kerberos (either by typing in a password to kinit, or loading a credential file).
Of these, my personal preference would be Kerberos if that service is supported on the network in question. Second best would be LDAP, because it allows centralized control over things like password changes and revocation. And third would be the regular password mechanism, which works in any environment.
Details on all of the available mechanisms are here: https://www.postgresql.org/docs/10/static/auth-methods.html
You cannot.
If the user has a direct access to the application (they can directly launch it) everything that is hardcoded in the application should be seen as accessible to the user. Whatever obfuscation you can use, a determinated attacker will be able to find it (through decompilers an debuggers).
If a break point exist, all is different:
front end application back end application
launched by user --/--> launched with a sytem user
local machine local or remote machine
This is typically the use case for web applications: the user has no access to the application code, and does not launch it, so the database password can lie in a configuration file - it will always be accessible to administrators. Even when all runs on the same machine, decent OS allows for access protection to prevent unprivileged users any access to the backend program. For that latter case, the front end and backend can communicate through sockets, named pipes, messages or almost any other IPC mechanism.
TL/DR: only secure way:
split the application into a front end running under user account with no knowledge of the database server, and a back end running under a system (non admin) user
ensure that normal users have no access to the backend application files
store the database password in a configuration file of the backend (never in a source file)
Related
For a reporting application deployed on AWS it is required to enable SSO for the users to access it -
The users are to access the application from their office PCs only within the company network.
The application endpoints are protected by an API gateway to only allow access from internal company network.
Once the user clicks on the URL for the reporting application, the app should authenticate the logged in user with the enterprise AD to ensure that the logged in user is a valid one and that they belong to the correct AD groups that are allowed access to the application.
If the authentication and authorization check is passed then the application should allow access to the user or else prompt up a login page to enter the credentials manually.
Can you advise what would be the best approach to set this up ? We have ADFS deployed on our company infrastructure (not sure of the version) so was wondering if we could use that or instead rely on Windows Kerberos authentication to get tokens to allow the user access.
What would be a better approach or more importantly what would be faster to setup. Completely new to SSO and ADFS in general so appreciate your responses.
Thanks!
Raunak
I would recommend you to use ADFS as it is much easier to integrate web apps with ADFS compare to Kerberos.
Kerberos might be tricky. I see you mentioned the reporting app will only be used from company's internal network, but you may still get into the troubles with Kerberos because it requires certain browser setup on the end user machines. On Windows you will have to ensure some IE settings:
IE -> Internet Options -> Security -> Local intranet -> Custom Level -> Make sure you have "Automatic logon only in Intranet zone" is selected.
IE -> Internet Options > Advanced -> make sure "Enable Integrated Windows Authentication" is on
It is very likely that you will also need to add your reporting application URL to the list of intranet sites and trusted sites on each user's PC (in case you use a custom domain name for your app, i.e. not an local server name in your domain)
Other browsers than IE may need a different setup, you can read more details here
I believe it is also a bit more complicated to work with the AD groups as you can only get a user name from a Kerberos token. Then you will have to make an additional call directly to AD to find user's groups. With ADFS you can get groups right from the token (as claims).
Here is a good manual on how to integrate your web app with ADFS: https://auth0.com/docs/connections/enterprise/adfs
We have a server with services and client side mobile app (Android, iOS). User authenticates with username/password but what about app itself? I want to limit access to server just to my app and I don't want to involve user in it, I want to keep it separated from user login process.
First idea is to keep some kind of key, password, certificate or the like in app (and use it to encrypt random challenges from server) but because it's hardcoded it can be taken out from code and used by some other app.
If phone has some security storage to keep certificate, password for accessing it will be kept in app so again it can be digged out.
You can have a database of "trusted" app devices and link that to your user or device database (a.k.a. who's using who). You can try the one-time password approach (behind the scenes with the app code) and authenticate every time the user interacts with the app.
I also agree that everything (hardcoded / stored) in the device may be obtained so time-based solutions may be effective in reducing attempts to do unauthorized actions.
I am working on a cross platform app that will be created using C++-> mobile devices, and using Perl-> Desktop PCs (like Windows /Linux/Mac OS).
Now, since the app will be downloadable, I have concerns regarding the ability of hackers to obtain the source code of my app.
Specifically, the app will connect to my central database-- at the minimum, I want that hackers are not able to obtain my database connection details. Ideally, I would want no part of the code to be hacked.
Basically, the user can update some of his information using this app-- if hackers get hold of this data they can easily change any unfortunate user's data. One thing that I have thought of is that the user will have to initially authenticate with OAuth/OAuth2 ( using his email ID #yahoo/#hotmail/#gmail)-- and only after that the app will actually show the admin interface. But at any rate, at some point the app will connect to the central database-- which is why I dont want the database's access details to be compromised.
Many organisations make such apps, so they must be facing this type of problem themself? I would like to know how I can protect my app (ideally entire code), and atleast the db credentials.
The simple answer is you do not expose your database. Ever.
Add a service layer (could be HTTP-based but doesn't have to be) on top that will deal with authentication and authorisation. Your app then logs in using the user's credentials and acts on their behalf. Your service layer exposes an API which your application talks to, but your service makes and controls all calls to the DB.
You already mention OAuth - that's a perfectly acceptable way of adding authentication to such an API.
You cannot.
On the bright side you can put security on your server. The connecting client provides credentials that they are a given user. The server generates the SQL command after proving the request is allowed. Backers can do anything your app can do, but your app becomes incapable of behaving badly to your database.
The previous answers are absolutely correct. You want a server based service layer that provides the authentication/authorization code and interacts with the database. However, it isn't always a perfect world and if you are stuck with the requirement that these applications must act as a database client you want to limit the exposure as much as possible. Typically this is done by having the client use a specific account which has not been granted any access to the general database. You then create specific stored procedures that can only do the operations and queries that are required of the application. This prevents anyone finding the credentials in the code from doing anything in the database that isn't intended, but you still have the problem that anyone can impersonate someone else by reviewing the code. There isn't a way to prevent that without a server side component. This might be okay for a closed/trusted group of users, but I wouldn't release anything to the general public with this method.
If you can do it, use OAuth2 and allow a trusted third party handle authentication. Twitter, Facebook and GitHub are all relatively paranoid about security; and the other poster is correct: never expose direct db access as part of the app the user has access to; put it behind a service of its own.
Good luck! :)
So I want to do the following:
A person registers online and selects their login and password for a desktop and web application (same login and password for both applications)
They then download the desktop application (written in C++ with Qt as it's cross platform)
Then the login and password is automatically passed to the desktop application without the person needing to enter this data. The login and password is used to authenticate with the server.
Each version of the desktop application needs to be individually coded with the person's login and password based on the fact that they signed up on the web page.
So here is a more simple explanation:
1. The user signs up on the web site and choose login\password
2. The user download desktop client on his computer
3. The user runs desktop client (C++ binary) and it asks for a login/password from the step
I would like that software fill in login/password automatically on step 3 for the first time. Is it possible? How would it be done without security risks?
The main problem is, that anyone could execute the program and gain access to a user account. I would suggest using a one-time login for first authentification with random tokens and after the first start, get the user/password information through an ssl-connection. After that delete your one-time login token and replace it with the actual login.
I don't really know whether you're asking for precise code examples or just want to have a basic concept... But anyway, storing login-data in the application itself is a security risk.
Have you look at HTTP Authentication?
I do not fully understand the download process of the QT app, but, if you use a Basic/Digest Authentication on your web server, propagating the authenticate token will be easy and safe.
Basic use a 64 base encoding, Digest a MD5 hashing. A lot of library implements those steps out there (Spring Security and Shiro in the Java world).
I saw two ways:
the server can provide a user with unique link for downloading installation package. The server patches that package by unique one-time password. So client will be able to login for a first time
the browser collects some information about a user's computer. For example, IP, MAC, OS Version, etc. Then it calulate digital sign of the computer based on these data. The C++ binary do the same. You can use that digital sign as one-time password.
I have a web application containing two web services, let's say PublicHello.asmx and RestrictedHello.asmx.
PublicHello must be accessed from anywhere, without requiring login. RestrictedHello must be accessed only from domain through Windows authentication (and its behavior is different from one user to another).
In IIS,
if I enable both Anonymous Authentication and Windows Authentication, then RestrictedHello always shows that the user is not logged in (even if credentials are correctly send).
if I enable only Windows Authentication, then PublicHello requires login.
Is there a way to use different authentication levels for different web services in the same web application/virtual directory?
I imagine it is impossible, but I'm not sure...
Check out the location element in the web.config file. Please see:
http://msdn.microsoft.com/en-us/library/b6x6shw7(v=vs.100).aspx
and
http://msdn.microsoft.com/en-us/library/ms178692(v=vs.100).aspx
To quote:
By using the location element with an appropriate value for the path attribute, you can apply configuration settings to specific folders and files.