Secure MySQL connection in Java? - java

I try this:
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sonoo","root","password");
but it's very easy for someone to hack strings of username and password.
Opening Application with zip, winrar or any else program look like this and read code.
How can I secure my connection?

You need to decide what permissions someone who gets a copy of your JAR has. Do they have permission to run database queries or not?
If they should not: delete the database connection. They don't have permission.
If they should: then they can have the password. They have permission.
What seems to be tripping you up is that you are giving out the root password for your database, and so you want the the third option: "They should be able to do some database queries, but not others."
The JAR file is the wrong place to try to solve that problem. If you try to solve this at the JAR file level, one of two things will happen. Either your users were trustworthy all along and you wasted your time with whatever elaborate scheme you used, or some of your end-users are untrustworthy and one of them will hack you. They will hack you by stepping it through the JVM and editing your query strings right before the JVM sends them out, at the very last second, if they absolutely have to. Everything you do at this level will be security theater, like getting frisked at the airport, it doesn't make you significantly safer but there is a tiny chance that you can say "but we encrypted it!" and your clients might not dump you after the inevitable security breach.
That problem needs to be solved within the database, by creating a user account which does not have the permissions that they should not have. When you do SHOW GRANTS FOR enduser#'%' it will show you only the sorts of queries that they are allowed to do.
In many cases you want to give the user account a more fine-grained permission than just INSERT, SELECT, or UPDATE on a table. For example, you might have the logic "you can add to this table, but only if you also update the numbers in this other table." For these, you should use stored procedures, which can have their permissions set to either "definer" or "invoker": define it by a user with the appropriate permissions and then the invoker gets to have advanced permissions to do this particular query.
In some cases you have a nasty situation where you want to distribute the same application to two different clients, but they would both benefit significantly (at the expense of the other!) from being able to read each other's data. For example you might be an order processor dealing with two rival companies; either one would love to see the order history of the other one. For these cases you have a few options:
Move even SELECT statements into stored procedures. A stored procedure can call user() which can still give you the logged-in user, even though they are not the definer.
Move the database queries out of the shared JAR. Like #g-lulu says above, you can create a web API which you lock down really well, or something like that.
Duplicate the database, move the authentication parameters to a separate file which you read on startup.
Option 3 requires you to write tooling to maintain multiple databases as perfect duplicates of each other's structure, which sucks. However it has the nice benefit over (1) and (2) that a shared database inevitably leaks some information -- for example an auto_increment ID column could leak how many orders are being created globally and there might be ways to determine something like, "oh, they send all of their orders through this unusual table access, so that will also bump this ID at the same time, so I just need to check to see if both IDs are bumped and that'll reveal an order for our rival company".

You can create a webservice in PHP (or java or others). This webservice is stocked on a server and he's contain access and query to your database.
With your desktop app, just send a request (POST, GET) to your web service.
Exemple in PHP webservice :
if (isset($_POST['getMember'])){
do a query in your database
insert result into JSON
return JSON
}

Related

Is it okay to validate JSON at PostgreSQL side?

Writing APIs I used to validate all input parameters on the Java (or PHP, whatever) side, but now we moved our DBs to PostgreSQL which gives us great JSON features, like building JSON from table rows and a lot more (I didn't find anything we can't to without PGSQL JSON-functions so far). So I thought what if I do all parameters validation to Postgres (also considering that I can return JSON straight from database)?
In Java I made it like this:
if (!params.has("signature"))
//params comes from #RequestBody casted to JSONObject
return errGenerator.genErrorResponse("e01"); //this also need database access to get error description
On a Postgres I will to that like this (tested, works as expected):
CREATE OR REPLACE FUNCTION test.testFunc(_object JSON)
RETURNS TABLE(result JSON) AS
$$
BEGIN
IF (_object -> 'signature') IS NULL --so needed param is empty
THEN
RETURN QUERY (SELECT row_to_json(errors)
FROM errors
WHERE errcode = 'e01');
ELSE --everything is okay
RETURN QUERY (SELECT row_to_json(other_table)
FROM other_table);
END IF;
END;
$$
LANGUAGE 'plpgsql';
And so on...
The one problem I see so far is that if we move to MS SQL or Sybase it will need to rewrite all procedures. But as NoSQL comes more and more now, it seems to be unlikely and If we move to NoSQL DB we will also have to recode all APIs
You have to consider basically two items:
The closer you put your checks to the data storage, the safer it is. If you have the database perform all the checks, they'll be performed no matter how you interface with it, whether through your application, or through some third party tool you might be using (if even only for maintenance). In that sense, checking at the database side improves security (as in "data consistency"). In that respect, it does make all the sense to have the database perform the checks.
The closer you put your checks to the user, the fastest you can respond to his/her input. If you have a web application that needs fast response times, you probably want to have the checks on the client side.
And take into consideration an important one:
You might also have to consider your team knowledge: what the developers are more comfortable with. If you know your Java library much better than you know your database functions... it might make sense to perform all the checks Java-side.
You can have a third way: do both checks in series, first application (client) side, then database (server) side. Unless you have some sophisticated automation, this involves extra work to make sure that all checks performed are consistent. That is, there shouldn't be any data blocked at the client-side that woud be allowed to pass when checked by the database. At least, the most basic checks are performed in the first stages, and all of them (even if they're redundant) are performed in the database.
If you can afford the time to move the data through several application layers, I'd go with safety. However, the choice to be made is case-specific.
So I found some keys... The main is that I can have my error messages been cached in my application that will allow to avoid making database request if input parameters doesn't pass it and only go to database to get the result data

Advice on using Shiro to restrict resultset

We have an application that allows users to see a list of documents.
Depending on the role of the user and the properties of the document, we want to filter out some of the documents on the list. For example we want to allow the user to view a list with only the documents that he created and a grey out line for the rest.
At the moment the application executes an SQL SELECT command which returns a list of entries that the user can and cannot see. We want afterwards to restrict this resultset according to the user's permissions and roles.
Our questions are the following:
Can this be done via Shiro?
What is the proper way to place such restrictions when using Shiro? e.g. shall we restrict the list from the start, using the SELECT statement ?
You have a few options:
First since it sounds like you want to display the full list of documents to the user you will still need to query all of them. (though I caution you on this, as that leaks information the user does NOT have access too. For example of user 'jcoder' sees a document titled 'Super Secret Passwords', he knows you have this document. That may or may not matter for your use cases)
If your use case is ONLY "only authors can edit their own documents" then you could just simple username comparison (which I'm guessing you are doing now)
Most use cases are NOT this simple, and require the author as well as administrators, tech writers, etc. access to the resource. So you could assign a set of permissions to the resource. We can call it publications:docs:<document_id>:<action>, or just docs:<document_id>:<action>. Where the document_id is some unique document identifier, and action what is being done to the resource (in a typical CRUD app they would be create, read, update, delete).
This permissions can be granted to any user and publications:docs:<document_id>:* could be granted to the author. This also allows permissions to be revoked if someone changes position or the document needs to be marked read-only too all users except administrators.
The snippet of code would look something like:
if(SecurityUtils.getSubject().isPermitted("publications:docs:":"+ documentId + ":read" ) {
// do something
}
Or you can check them them all at once.
Your application would need to keep track adding permissions to users.
Take a look at: http://shiro.apache.org/permissions.html
And a similar question: Java – efficient, database-aware instance-level authorization?

Is a good idea do processing of a large amount of data directly on database?

I have a database with a lot of web pages stored.
I will need to process all the data I have so I have two options: recover the data to the program or process directly in database with some functions I will create.
What I want to know is:
do some processing in the database, and not in the application is a good
idea?
when this is recommended and when not?
are there pros and cons?
is possible to extend the language to new features (external APIs/libraries)?
I tried retrieving the content to application (worked), but was to slow and dirty. My
preoccupation was that can't do in the database what can I do in Java, but I don't know if this is true.
ONLY a example: I have a table called Token. At the moment, it has 180,000 rows, but this will increase to over 10 million rows. I need to do some processing to know if a word between two token classified as `Proper Name´ is part of name or not.
I will need to process all the data. In this case, doing directly on database is better than retrieving to application?
My preoccupation was that can't do in the database what can I do in
Java, but I don't know if this is true.
No, that is not a correct assumption. There are valid circumstances for using database to process data. For example, if it involves calling a lot of disparate SQLs that can be combined in a store procedure then you should do the processing the in the stored procedure and call the stored proc from your java application. This way you avoid making several network trips to get to the database server.
I do not know what are you processing though. Are you parsing XML data stored in your database? Then perhaps you should use XQuery and a lot of the modern databases support it.
ONLY an example: I have a table called Token. At the moment, it has
180,000 rows, but this will increase to over 10 million rows. I need
to do some processing to know if a word between two token classified
as `Proper Name´ is part of name or not.
Is there some indicator in the data that tells it's a proper name? Fetching 10 million rows (highly susceptible to OutOfMemoryException) and then going through them is not a good idea. If there are certain parameters about the data that can be put in a where clause in a SQL to limit the number of data being fetched is the way to go in my opinion. Surely you will need to do explains on your SQL, check the correct indices are in place, check index cluster ratio, type of index, all that will make a difference. Now if you can't fully eliminate all "improper names" then you should try to get rid of as many as you can with SQL and then process the rest in your application. I am assuming this is a batch application, right? If it is a web application then you definitely want to create a batch application to do the staging of the data for you before web applications query it.
I hope my explanation makes sense. Please let me know if you have questions.
Directly interacting with the DB for every single thing is a tedious job and affects the performance...there are several ways to get around this...you can use indexing, caching or tools such as Hibernate which keeps all the data in the memory so that you don't need to query the DB for every operation...there are tools such as luceneIndexer which are very popular and could solve your problem of hitting the DB everytime...

How to find number of database round trips by an application

I am a java programmer and I want to know how many database calls/trips are done by my application. We use Oracle as our relational database.
With oracle, I got to know about a way to alter session statistics and generate the trace files. Below are the queries to be fired:
ALTER SESSION SET TIMED_STATISTICS = TRUE;
ALTER SESSION SET SQL_TRACE = TRUE;
After the trace files are generated, they could be read using the TKProf utility. But this approach cannot be used because:
my application uses hibernate and spring frameworks and hence the application does not have an handle to the session.
Even if we get the trace files, I need to know whether the set of queries are fired in one go (in a batch) or separately. I am not sure if TkProf output could help to understand this.
Does anyone have any better suggestions?
In TkProf, you can basically tell the number of round-trips as the number of "calls" (although there are exceptions so that less round trips are required, e.g. parse/execute/fetch of a single row select is, theoretically, possible in a single round trip, the so called "exact fetch" feature of oracle). However as a estimate, the tkprof figures are good enough.
If trace wait events, you should directly see the 'SQL*Net from/to client' wait events in the raw trace, but I think tkprof does not show it (not sure, give it a try).
Another way is to look into the session statistics:
select value
from v$mystat ms, v$statname sn
where ms.value > 0
and ms.statistic#=sn.statistic#
and sn.name IN ('SQL*Net roundtrips to/from client')
However, if you do that in your app, you will slowdown your app, and the figures you receive will include the round-trips for that select.
A wrote a few articles about round-trip optimization:
http://blog.fatalmind.com/2009/12/22/latency-security-vs-performance/
http://blog.fatalmind.com/2010/01/29/oracle-jdbc-prefetch-portability/
Firstly, use a dedicated database (or timeframe) for this test, so it doesn't get easily confused with other sessions.
Secondly, look at the view v$session to identify the session(s) for hibernate. The USERNAME, OSUSER, TERMINAL, MACHINE should make this obvious. The SID and SERIAL# columns uniquely identify the session. Actually the SID is unique at any time. The SERIAL# is only needed if you have sessions disconnecting and reconnecting.
Thirdly, use v$sessstat (filtered on the SID,SERIAL# from the v$session) and v$statname (as shown by Markus) to pull out the number of round trips. You can take a snapshot before the test, run the test, then look at the values again and determine the work done.
That said, I'm not sure it is a particularly useful measure in itself. The TKPROF will be more detailed and is much more focussed on time (which is a more useful measure).
Best would be to get a dedicated event 10046 level 12 tracefile of the running session. You will find there all information in detail. This means that you can see how many fetches the application will do per executed command and the related wait events/elapsed time. The resul can be analyzed using tool from Oracle like TKPROF or Oracle Trace Analyzer or Third party tools like [QueryAdvisor][1].
By the way you can ask your DBA to define a database trigger activating Oracle filetrace automatic after login. So capturing the file should not be the problem.
R.U.
[1]: http://www.queryadvisor.com/"TKPROF Oracle tracefile analysis with QueryAdvisor"

How to deal with private/public pictures of a user created image gallery?

I am working currently on a web project where users can create image galleries and upload pictures. Optionally they can mark pictures as private so that nobody else can look at them.
Now i am not sure how to properly implement the protection mechanism. Of course i have some ideas but none of them seems to be optimal.
Here is one of my ideas:
Create a table for user images:
image_key (PK) | user_id | public_image (boolean)
the picture will be saved on the harddisk using the iamge_key and can be accessed via http by an url looking like this:
http://www.myCompany.com/images/image_key
a servlet will be mapped to the url path images, the key will be extracted, a stream to the file on the harddisk will be openend and the picutre will be streamed.
additionally there will be a reverse proxy in front of the servlet container to provide some caching.
The issue with this solution is that my serlvet would have to go to the database and check if the image with the given key is public or not.
My question:
Can this be done without hitting the database? (some fancy ideas)
Can someone provide a better solution to store and keep track of the pictures?
How would a solution look like where besides public and private pictures also some pictures are shared to firends only?
Please note that this question is not about storing pictures in a database or somewhere else but concerns access rights management of binary resources in a web application environment.
If the DB table is properly indexed and you're using a connection pool, then hitting the DB is cheap. I would just keep it as is. You can at highest have a copy of the table in a Map in the application scope. But this may eat too much server memory. If you're using an ORM framework like JPA/Hibernate, you could also just turn the second level cache on to delegate the caching to the ORM. It will generally do its job very well.
As to the client side caching, you'd like to have a short expire time (1 hour?) and provide a doHead() in the servlet which in turn does basically just the same as doGet() but then without writing any bit to the response body. You would also like to check for If-None-Match and If-Last-Modified headers in the servlet if the client supplied them. You can find here a basic example of a servlet which does that.
My question: Can this be done without
hitting the database? (some fancy
ideas)
Yup, you can do it without hitting the database. We've got something similar and just wanted to put something quick in place.
The user is marking the resource private or public when he's uploading it.
We do something very simple:
public resources have a "tinyurl like" URL, say: abcd.org/aZ3tD (part of the point of the very short tinyurl-link thing is so that people who want to cut/paste/twitter it don't have to use an additional layer of bit.ly or tinyurl)
private resources aren't meant to be shared nor archived, so users don't care about a URL looking like: abcd.org/private/da499c3314e2fdce6a10a8b985489671971c187d
The first part of that URL is the user's ID.
So only the user da499c3314e2 (which must be logged in) can access resource fdce6a10a8b985489671971c187d
You asked for some way to do this without hitting the DB, this should work...
To avoid having to go to the database so often, how about the following URL patterns:
1. http://www.mycompany.com/images/<user_id>/public/<image_key>
2. http://www.mycompany.com/images/<user_id>/private/<image_key>
3. http://www.mycompany.com/images/<user_id>/shared/<image_key>
For 1, obviously no DB lookup is required - the image can be served to anybody immediately. For 2, your servlet would have to check that the ID of the active user matches the user_id in the request - again, hopefully no DB lookup required, just a check of a session variable.
The only case in which a DB call would be needed is 3, to check the relationship between the requesting user and the user who owns the image.
Of course, you'll need to be very careful about caching to ensure that your cache doesn't serve up private or shared images to unauthorised users...
Another alternative can be to store such information in image metadata.
Image metadata API: http://download-llnw.oracle.com/javase/1.4.2/docs/api/javax/imageio/metadata/package-summary.html
You can find related example:
http://download-llnw.oracle.com/javase/1.5.0/docs/guide/imageio/spec/apps.fm5.html
Write dpi metadata to a jpeg image in Java

Categories