Is JDBC connection to a remote database over the internet without SSL but authentication with username and password enabled is insecure ? Is attack like man in the middle possible for such scenarios ?
Authentication NOT implies confidentiality. SSL/TLS was born to grant the latter. So you have to use a secured connection. But I'd suggest you to not expose you DB to the Internet. Use a microservices-like pattern to isolate the DB from unwanted exposures.
It is insecure, never expose your database on internet, not even using ssl. If you really need to do so, make a ssh tunnel or configure a vpn.
Related
I'm developing a Java Swing based app which uses JDBC to connect to a MySQL database. As such, the software directly remotely access the database from whichever computer it happens to be running on. Additionally, the app uses prepared statements to query the database and the database is hosted on a shared CPanel hosting account (if that matters).
The snippet of code I use to connect to the database is as follows (fairly standard connect code I think and all strings in all caps contain the correct contents):
String url = "jdbc:mysql://URL:PORT/DB_NAME?connectTimeout=3000";
Connection conn = DriverManager.getConnection(url, USERNAME, PASSWORD);
I have only ever successfully used the app from one IP. Before I use the app from an IP, I have to manually whitelist the IP by adding it as an allowed remote MySQL access host. If I don't add the IP as an allowed access host, the server refuses my connection and I get the resultant error:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Then if I whitelist an IP and try to connect from it, I don't get that error and the app connects to the database properly.
This system would be okay if the app were only going to be used from one IP, but it needs to work from any IP since I cannot predict who will download and use it. The only solution I see would be to do a global whitelist of all IPs in the allowed MySQL access hosts area. However, that seems like it has many drawbacks, such as being insecure as anyone who has the correct password could log in (and would thus be susceptible to brute force attacks). This seems to corroborate the hypothesis that that method is insecure. Thus, I would like to have a system of communicating between the app and database that is IP-independent (doesn't require whitelisting all the IPs).
Additionally (I don't know if this makes sense or matters), but I believe some of the areas I expect the app to be used in block certain protocols. Thus, (I think) I would like it if the selected method of communication only used HTTP or some other widely-used protocol.
I did some research into this problem and my efforts led me to 2-tier and n-tier models of database communication. Perhaps I could do something like make a PHP page which accepts a statement and a series of parameters (plus a password to gain entry), executes the statement, and then returns the result back as JSON. However, this seems like another less-than-ideal method as it seems like it would also have security problems.
I'm sure someone more experienced and knowledgeable than I has already come across this problem and developed a solution.
Therefore, my question: What is the preferred method of connecting to a MySQL database from a Java app in an IP-independent way?
I greatly appreciate and thank you for your time.
You're on the right track:
1) If you want any arbitrary client to connect directly to your database, and the clients can have any arbitrary IP address ... then you're probably going to have to effectly disable IP security be whitelisting all possible client IP addresses.
2) On the other hand, if you only allow local access to mySql (by far the most common scenario), then you can create a web app to interface between your clients and mySql.
SUGGESTION:
Consider creating a "REST" web service that your clients can talk to.
Here's a good tutorial that might help you get started:
REST with Java (JAX-RS) using Jersey - Tutorial
Q: Does your Swing app really need to emit "raw SQL"? Or can it make "high level" queries? REST is ideally suited for the latter.
PS:
Here's another, short example that might help suggest some design alternatives with REST, mySQL and Java for you:
http://www.9lessons.info/2012/09/restful-web-services-api-using-java-and.html
You are up against the policies -- primarily the security policies -- of your hosting provider. It's generally considered insecure to allow port 3306 (MySQL) connections from the whole internet. It certainly lays your MySQL server open to trivial denial-of-service attacks. (It just takes some knucklehead controlling a botnet to send in lots of port 3306 connection attempts. They don't even have to be successful connection attempts.) If you're sharing your MySQL server with other customers of your hosting provider, they have every incentive to restrict your remote access to their server.
Most folks who build database applications for deployment on the public internet do it by providing web services to hit the database with the specific operations required by the application. The application deployed at the end-user's machine then uses HTTP (or HTTPS for security) to access those web services. In turn the web services access the database. That's what multitier operations do. You're right that there are security problems, but you can mitigate them with careful development of your web service code.
You could use SSH tunneling to handle your database access. The SSH suite of remote-access applications allows port forwarding. To use this, you would establish (authenticated and encrypted) ssh connections between your end-users' machines and your database machine, that forward port 3306. Then your users could connect to localhost:3306, and that net traffic would be forwarded to your database server. It's pretty flexible and quite secure, if not completely simple to configure.
You might also investigate using SQL Relay. It's generally used for connection pooling and management within a data center network, but it might work for this purpose.
Be careful opening up your MySQL server to the world! If you do that you may want to require the use of TLS encrypted conections.
In my application, I verify a the Android user's identity by giving each user a different client-side SSL certificate. I'd like to use HttpsUrlConnection to connect to the server since that's Google's recommended way.
The user can switch accounts (log out from the current one and log in with a different account). In this scenario, I need to estabilish the HTTPS connections with the new user account's client-side cert.
How will HttpsUrlConnection's connection pooling mechanism work in this environment? How can I force all HTTPS connections in the connection pool using the wrong client-side cert to disconnect?
With the, err, disconnect() method.
I have a sourceforge hosted MySQL database and the connection URL is as follows:
https://mysql-t.sourceforge.net:3306/"db_name"
I want to use JDBC to connect to this database.
My connection URL is as follows:
jdbc:mysql://https://mysql-t.sourceforge.net:3306
However, I keep getting the following error
java.sql.SQLException: Must specify port after ':' in connection string
The reason for this, I believe, is that the https:// part keeps expecting a port after the : sign, like https://<port#>
I could probably use getInetAddress() to retrieve the IP and use that, but I need a better solution since that might not be right.
Your URL should not include http or https. Try it like this:
jdbc:mysql://mysql-t.sourceforge.net:3306/db_name
You might be thinking that you have to include http or https because port 3306 is not visible to your client on the Internet. Be glad that it's not. If it's visible to you, it's visible everyone else, too.
You need an intermediary servlet between your client and the database. Clients can contact the servlet via http port 80 or https port 443. The servlet will authenticate and authorize them, validate and bind parameters, make requests to the database on their behalf, and send the appropriate response.
You should not be letting anyone use the root or admin credentials to access that database. You should create credentials just for that app, accessing only one database, allowing only the operations needed to do the job.
Problem fixed.
1) The access URL is different from what was provided. I found that out from the sourceforge forums where other users had similar problems.
2) The port number is different. It works at 4040 and not 3306.
3) Sourceforge apparently doesn't allow permanent access to their database. It works only on request and only for 4 hours at a time. They do not allow using their database as backend.
I am trying to connect to a mysql db on a shared server. I am using a java application to make the connection. Problem doesn't happen when I connect to localhost db.
URL = "jdbc:mysql://SHARED HOST IP:3306/DBNAME";
USER = "dbUSER";
PASS = "dbPASS";
Connection conn = DriverManager.getConnection(URL, USER, PASS);
java.sql.SQLException: Access denied for user 'DBUSER'#'mycomputersIP???' (using password: YES)
It is strange that it says denied for dbuser# mycomputersip instead of dbuser#sharedhostIP
Is there a setting on my wireless router that is screwing things up?
your database is not configured for remote access. basically its saying your user located at your ip doesn't have permission to access the database, as opposed to your user located at the web server.
if you are using a shared hosting package, you will either need to turn this on in your admin area, or it may not be supported by your host. some hosts additionally require that externally accessible databases may not be on the web server, so your connection string would likely change as well.
There are no settings screwed up on your router. If you are trying to connect from mycomputersIP (i.e. the program opening the JDBC connection is on your computer), then the database will need to grant permission to 'DBUSER'#'mycomputersIP'. (In fact, that is the point of that portion of the grant string.)
Just as VeeArr said, 'DBUSER'#'mycomputersIP???' is standard. For some reason your host exposes your database but isn't allowing you to connect. There's a way in phpMyAdmin to do it under Privileges if you manage the whole database or there's an option in your control panel. If not, then you need to contact your host for guidence
The Same problem I have got earlier, Its very simple, The access has been denied by your ISP to access DB,
Raise the request to grant access, it will work.
How does the SQL Server JDBC Trusted Connection Authentication work? (ie how does the trusted connection authenticate the logged in AD user in such a transparent and elegant fashion and how can I implement a similar authentication solution for my client-server applications in Java without a database connection or any use of the existing SQL Server solution.)
Assumptions
* Working within a Windows 2003 domain
* You have access to the Windows API via JNI/JNA
It depends on the client. For example if you have a Web Browser, it can use the NTLM Authentication to pass the domain authentication of your current client to the server. In this case the browser like IE or FF supports this, and you web server needs the support for NTLM. For example here for Tomcat: http://jcifs.samba.org/src/docs/ntlmhttpauth.html
There is also the SPNEGO protcol in combination with Kerberos, as explained here: http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/lab/index.html
If you have your own client, it depends on the client's framework if it is able to use the local user's security context and is able to pass it on. The page above describes this at least for a kerberos scenario.
Greetings
Bernd
PS: I am not sure if you can pass the authentication context established with the jcifs/ntmlm solution to a backend component like SQL Server. It should work with Kerberos tickets (if configured).
jTDS and Microsoft JDBC Driver both offer native Windows Authentication.
Have you looked at this question? The situation seems to be similar to yours (connecting to a SQL Server database using Windows authentication).