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
Related
I have always used a database located in my pc, so the steps to connect to it are:
connect to my local db using jdbc
perform queries
show results
now, i want to know what are the steps if the database is located in an online server?
some guides,tutorials are very appreciated.
Since you will be connecting to a remote database I would advise you to read about secure connections using JDBC. See this question, for example. You don't want to interact with a remote database without something like SSL to protect the confidentiality of the data.
Once you think you have secured your connection, you can use a tool like Wireshark to make sure that the packets that are going to and coming from your database are in fact opaque.
Furthermore, as others have said, not much changes if you already have a working connection to a local database, it's a matter of changing your URL from jdbc:mysql://localhost:port/database to jdbc:mysql://ipaddress:port/database.
From my experience, I found that some hosting companies block database access from unknown IP addresses, so it's possible that you'll have to go to your CPanel and whitelist your IP address.
Once your database connection is setup, the code you use to query the database should look the same.
Some useful links:
JDBC Best practices
JDBC Tutorials from Oracle
You have to change database url only to be like
jdbc:mysql://IP:3306/databasename
also username and password.
some hosting company like godaddy create database in localhost(in the same host) which doesn't need to change anything in your code.
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.
I have a java application that connects to an external sql database using jdbc 4. It uses prepared statements to select data from the database and also to send updates. Can the data that's transferred between the database and my application be classified as encrypted or are there further steps I would need to take in my application for it to be encrypted?
No, PreparedStatement does not equate to encryption. You would need to enable (better yet if you can require it; my familiarity is with postgresql rather than mysql) SSL on the server and set up a certificate and private key. You would then need to instruct your application to use SSL and to accept (only) the certificate belonging to the server.
Note that SSL and encryption in transit, while useful, does not protect the data from an attacker who gains access to the database.
PS. Most likely ServerFault would be the best resource for answers regarding how to configure mysql.
Edit for follow on: According to the documentation the credentials in the initial connection are secured.
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 am looking for way to store some data. I want to users of my program to be able to choose a way to store data. They can choose database (PostgreSQL, MySQL) and I want to give opportunity to choose easier way for newbie users so they don't have to install database system. When they start my program for the first time they're passing user data (login/password) and the some data made by my program are stored on HDD of user. Is it any library (for Java) or something like db but configured automatically when that let me do this? I mean, I want to create some tables like in db and have an easy access to them. But they should be secured (access only with login/password passed at the first time). I hope you will understand me. It was difficult to explain what I want :)
You could use an embedded DB, like Apache Derby. See also the Working with encryption article.
If i'm understood right you need embedded SQL DB engine that can store data encripted? Take look at h2 databse
it's lightweight and has this
Security Features
Includes a solution for the SQL injection problem
User password authentication uses SHA-256 and salt
For server mode connections, user passwords are never transmitted in plain text over the network (even when using insecure connections; this only applies to the TCP server and not to the H2 Console however; it also doesn't apply if you set the password in the database URL)
All database files (including script files that can be used to backup data) can be encrypted using AES-128 and XTEA encryption algorithms
The remote JDBC driver supports TCP/IP connections over SSL/TLS
The built-in web server supports connections over SSL/TLS
Passwords can be sent to the database using char arrays instead of Strings