I'm using JDBC to connect to a PostgreSQL database. We are trying to block access to the database for the users themselves; instead they should be forced to use our frontend. We blocked access to any table, and gave only procedures, which do all the work for users, still not giving them any opportunity to access data directly. We tried to block access to schema pg_catalog, which limits users to procedures we created, but it seems that this access is needed for JDBC to call any procedure.
Anyway, the question is either how to use JDBC without access to pg_catalog, or how to authorize only connections made by application, not user.
There is no fool proof way but the simplest is to use a username and password for the connection that you do not give to your users. Store the password in an encrypted configuration file. Ofcourse the encryption key can be retrieved from the application by a smart person.
For a really save system it would probably be best to put a service in front of the database that handles all security and provides a high level API to access the data and let the client connect to this.
The DBMS is being presented with a Catch-22 situation:
When a user runs a specific JDBC program to access the database, let it do its stuff.
When a user runs any other JDBC program to access the database, do not let it do its stuff.
How can the DBMS tell the difference between the two programs? As far as it is concerned, they are both clients that are using the correct protocol to communicate with the DBMS, and have identified themselves as a legitimate user of the database.
To make it work, you have to find a non-subvertible way to distinguish between the two applications. That is not trivial - to say the least.
There are kludges, but there isn't a clean solution. It is a generic problem that any DBMS faces when the problem is presented as in the question.
Well, just don't give your users an account on your postgresql database and create only an postgresql account for your application.
Related
I am intending to have a console on my web app so I can run queries directly from my browser. I can only find guides on how to connect the h2console to an in-memory DB instance. Is this possible? Security isn't an issue, this is strictly for testing purposes, only my ip address will be allowed to connect to the site (for now).
I think you are confusing some things here: h2 is an in-memory-database. There is NO persistent storage. MySQL is a proper RDBMS. I would not expect you to be able to connect to mysql through that interface.
If you just need to be able to execute queries from your web application, and it is not going to go public, simply create a page with a textarea, send that to the backend using JDBC. If I have misunderstood your question, please add additional details to it so we cn provide a better answer.
I have a SQL databse on the internet which has information
I need my Android app to be able to access that information
The app needs to know the username and password of the database
How can it know?
If i code it in, anyone can get it
In general, databases should not be publicly accessible, nor should they be directly accessed by a user application, for several very good reasons:
There is generally no easy way to implement row-level access control. Views and triggers can only get you so far - in general application-level users do not map well to database users, since the latter usually have access to far more data than the former should have.
The DB clients are tied to the actual database schema. Having clients not under your control like, say, an Android application is a very good way to tie yourself up in ways that would disallow any and all future development.
Having a DB port open to the world is not considered by any means secure. Any potential security hole would give straight access to all of your data. The MySQL security guidelines explicitly warn against opening the DB port to the internet.
There is no way to protect the DB credentials or the data from a sufficiently determined and knowledgeable user. If your application can access something, so can they.
Database access protocols are mostly designed with local-area networks in mind, rather than the inherently unreliable nature of the Internet. Even encryption and security are often more of an afterthought...
The standard way to approach this issue is to create an intermediate web service with separate user accounts and a restricted set of operations on the data. The web service would let each user access only the data that relate to them, and even that indirectly. This approach separates the data from the user application layer, allows you the flexibility of storing and accessing your data however you wish and provides an additional layer of security for your DB.
I have a JAVA application (Jersey, Hibernate, Spring) which is using MySql as database. Application is running completely fine. Now my client wants me to encrypt all data in database because it hold some confidential information as well. so for example if anybody directly logs in to MySQL he/she should not be able to view actual data but the encrypted data.
Actual data should be shown in correct for only using application.(In application we are maintaining user rights).
Please suggest do I need to make change at application layer. Application is quite big and if make changes for each and every query while inserting and retrieving data, it would take alot of time. Please suggest if there is any alternative way.
Regards,
Alex
MySQL does not provide transparent data encryption by default. I quick googling reveals some add on products that claim to do what you are looking for (personally, do not have any experience with them):
zNcrypt for MySQL
MyDiamo
I think you should evaluate these options.
I have an Apache Derby database that, until now, has always been locally accessed. It needs to be accessed by multiple computers now, so I feel it ought to have a username/password.
How do I take the existing database and retroactively add a user
How do I provide local/network authentication for that user?
I recall looking through their docs a few years ago, and it seem like there was a lot left to a developer to implement in these cases.
To clarify more, regarding point #1, this page says:
Attention: There is currently no way of changing the database owner once the database is created. This means that if you plan to run with SQL authorization enabled, you should make sure to create the database as the user you want to be the owner.
I think this means that I will probably have to create a new database with a named user, and migrate all date from the original single-user database to the new one. Is this correct? Is there an easier way?
Also regarding question number two, the manual says
Important: Derby's built-in authentication mechanism is suitable only for development and testing purposes. It is strongly recommended that production systems rely on an external directory service such as LDAP or a user-defined class for authentication.
Which, to me, says that the builtin authentication isn't worth using. There's no way we're going to go to an LDAP integration either, so is there something in-between these two that is worth using?
Since you mention you're going from a single-user environment to a multi-user environment, you're probably going to be setting up the Network Server, so you will have two levels of security to consider: database authentication, and network server authentication.
You probably want to start here: http://db.apache.org/derby/docs/10.8/adminguide/cadminapps49914.html
and here:
http://db.apache.org/derby/docs/10.8/devguide/cdevcsecure42374.html
I've been tasked with making an enterprise application multi-tenant. It has a Java/Glassfish BLL using SOAP web services and a PostgreSQL backend. Each tenant has its own database, so (in my case at least) "multi-tenant" means supporting multiple databases per application server.
The current single-tenant appserver initializes a C3P0 connection pool with a connection string that it gets from a config file. My thinking is that now there will need to be one connection pool per client/database serviced by the appserver.
Once a user is logged in, I can map it to the right connection pool by looking up its tenant. My main issue is how to get this far - when a user is first logged in, the backend's User table is queried and the corresponding User object is served up. It seems I will need to know which database to use with only a username to work with.
My only decent idea is that there will need to be a "config" database - a centralized database for managing tenant information such as connection strings. The BLL can query this database for enough information to initialize the necessary connection pools. But since I only have a username to work with, it seems I would need a centralized username lookup as well, in other words a UserName table with a foreign key to the Tenant table.
This is where my design plan starts to smell, giving me doubts. Now I would have user information in two separate databases, which would need to be maintained synchronously (user additions, updates, and deletions). Additionally, usernames would now have to be globally unique, whereas before they only needed to be unique per tenant.
I strongly suspect I'm reinventing the wheel, or that there is at least a better architecture possible. I have never done this kind of thing before, nor has anyone on my team, hence our ignorance. Unfortunately the application makes little use of existing technologies (the ORM was home-rolled for example), so our path may be a hard one.
I'm asking for the following:
Criticism of my existing design plan, and suggestions for improving or reworking the architecture.
Recommendations of existing technologies that provide a solution to this issue. I'm hoping for something that can be easily plugged in late in the game, though this may be unrealistic. I've read about jspirit, but have found little information on it - any feedback on it or other frameworks will be helpful.
UPDATE: The solution has been successfully implemented and deployed, and has passed initial testing. Thanks to #mikera for his helpful and reassuring answer!
Some quick thoughts:
You will definitely need some form of shared user management index (otherwise you can't associate a client login with the right target database instance). However I would suggest making this very lightweight, and only using it for initial login. Your User object can still be pulled from the client-specific database once you have determined which database this is.
You can make the primary key [clientID, username] so that usernames don't need to be unique across clients.
Apart from this thin user index layer, I would keep the majority of the user information where it is in the client-specific databases. Refactoring this right now will probably be too disruptive, you should get the basic multi-tenant capability working first.
You will need to keep the shared index in sync with the individual client databases. But I don't think that should be too difficult. You can also "test" the synchronisation and correct any errors with an batch job, which can be run overnight or by your DBA on demand if anything ever gets out of sync. I'd treat the client databases as the master, and use this to rebuild the shared user index on demand.
Over time you can refactor towards a fully shared user management layer (and even in the end fully shared client databases if you like. But save this for a future iteration.....