Actually Iam writing a plugin for an java app that comes in two flavours 1.)as executable and 2.) can be launched from a webpage as an applet.
At some point I needed a custom form that displays various data from an oracle database. I build that form and the class that does the jdbc query needed.
Now when it comes to the executable the form pops up correctly with the expected results, but when I try to call it from the applet it launches with all fields empty and no error whats so ever.
The only thing I can think of is that due to the asychronous nature of the web, the form pops up before the query returns the result.
If that is true, is there a workaround?
I believe that you just catch exceptions and therefore do not see them. Or just do not know where to search for them. Did you open applet console? I believe that you will find some exception there.
Applet is not different from application. Applet just has security restrictions. It cannot perform TCP connection to server other than one it was downloaded from. And important: the security check is pretty stupid. It is based on string comparison. It just compares host names of applet base and the host name of host where you want to connect. If for example your host name is myhost.mycompany.com and its IP is 200.201.202.203 you have to use either DNS name or IP address in both places even if ping of DNS name returns your IP adderess. Check this and I hope everything will work.
BTW, do you probably know that you are using "old", "obsolete" design? This is the beginning of 90s design. People switched to N-tier architecture ~12 years ago, so, to improve your solution you should implement DB access on server side and talk to server via some kind of protocol, e.g. rest API.
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.
It seems that with the latest Java update, 1.7.0u45, my JNLP application that is supposed to connect to a server is instead forced to try and connect to localhost for some reason that I cannot quite seem to figure out.
I know that some other changes have been made, such as requiring the Permissions attribute in the manifest and some such things, which I'm currently trying to figure out a reasonable way to comply to, but I cannot find anything that ought to cause this behavior.
My code just does an ordinary Socket.connect call to a specific server, but what happens is that the connection is instead made to localhost. This only happens when the code is running in the JNLP client; not when I run it "manually" by starting the VM on it.
Does anyone know why this is?
At last, I managed to figure out what was happening. It was not, in fact, that connections as such were being redirected, but rather that the JNLP client has started blocking JNLP files that are not signed from setting system properties with certain names. Particularly, only properties whose names begin with jnlp are, it seems, guaranteed to be configurable by unsigned JNLP files.
The problem, therefore, was that I specified what server to connect to via a system property whose name did not begin with jnlp, and it then being blocked (since my JNLP file isn't signed) led to my program using its default server specification instead, being localhost.
I need a secure way to send information from a Java application to a database for my website. I currently have a PHP page on the server that accepts the parameters posted from a URLConnection in Java, and then updates the database. My fear is that, if somebody decompiles it, they can see the exact URL and parameters. I am new to this type of development, so I don't know a better/safer way to do it.
What is a better or safer way to get the data to the database?
If you want to give the application access to the database then you can never 100% prevent any application simulating the behaviour of your application from having the same access. period. You can only make your pattern harder to be found.
Better is letting your server (in this case your php-document) validate each and every input it gets so that bad behaviour is excluded. Let the php generate querys and let the client-application only send the data needed like username, password or other information. in your php, you have to be prepared, that everything could be send, not only data you expect. Use prepared statements to prevent sql-injections and use regex to sanitise any input given.
If I understood well, you're afraid that someone will find out from your code url, username and password and connect to the database with these parameters. You can prevent that misbehaviour on network layer (i.e. allowing only your IP address to access the database by configuring firewall) or, if you cannot alter firewall/router configuration then change the database configuration. For example, PostgreSQL has a file pg_hba.conf where you can specify list of IP addresses that are allowed to access. However, you must prevent other vulnerabilites like SQL injection that use your connection to the database.
From the sounds it, your using a Java program to connect to your PHP/server. If your worried about the security of the connection, you could establish a SSL connection using HTTPS (example here)
You could also establish a challenge/response protocol, where the server requests some kind of key from the client, this could use a rolling series of public/private keys with the message encrypted with these to further reduce the chance of a false input request
I am making a Java based form desktop app, a mini login form, that will be able to login into a grand system which is online in asp.net.
The purpose of this app is to install on pcs, and whereever this exe is installed, the website could be logged in, other wise not.
The problem is, i have put the connection string of sql server in it, and employees will install this app on their machines, there is a tool available which decompile JAR and classes. And when i checked my classes in it, it was showing my sql server password. And it can give a chance to them to hack this app, this is really dangerous for us to provide them or give them a chance to get sql server password.
Can you please help, is there any such solution that i could give MD5 encrypted password or some encrypted password in connection string and sql server could be able to understand it.
Thanks
There are a few ways you can handle this.
the user info in your connection string should be limited to execute exactly one procedure: the one that tests if the MAC address is valid. This limits exposure. Not in an ideal way, but it's something.
Don't send a connection string at all. Instead have the java application post the mac address to a web service. The service should connect to the database server to determine authorization. Better than option 1.
Even better: Don't rely on MAC addresses. If you are worried that someone will look at the connection string then it stands to reason they might change their MAC address to mimic another machine. It stands to reason that anyone familiar enough to directly connect to a database server will also be familiar enough to download one of the many freely available tools to spoof their MAC.
Which leads to a comment: I think your doing this wrong. If the entire purpose of the java app is to simply read the MAC to validate whether that particular machine should have access then you have some serious issues with understanding security and I think you really need to evaluate what, exactly, it is you are trying to stop.
You can use integrated authentication, provided that the database server is in the same active directory domain as your users. Simply specify Integrated Security=SSPI in your connection string and grant regular users rights corresponding to what you want them to be able to do in the database (for example, read only access), but no more.
I have, let's say, a root website with mysql db on a remote server.
I want to connect to that particular database (to make queries), from many other little websites (with lower priviledges).
Can this be done?
Language: jsp, java, php
Any particular problem? Just specify server address instead of 'localhost' in connection string.
You can also create dedicated user with minimal privileges for that.
The default configuration often contains a variable
skip-networking
which you need to comment-out in order to have networking enabled.
Yes it can be done, MySQL allows connections from remote hosts (assuming MySQL is configured to allow network connections and assuming the remote hosts are granted). In case of problem, the section 5.4.7. Causes of Access-Denied Errors lists most common problems and solutions.
In addition to the answers from Nikita Rybak andPascal Thivent, I'd like to note that most hosting providers don't allow queries from locations other than localhost.
I don't know how much access you have to the server configuration, but I would have saved myself a headache a while back when I first started experimenting with connections across domains/servers.
If the MySQL server is under your control, it's not difficult; you can find the procedure here. If it's not, the only thing you can do is beg the admin to do it, otherwise it's impossible.