[Java][SQL] Hardcoded username and password on query - java

I'm having a problem with my java code. My teacher at university asked me to use "kiuwan" as online code evaluator and he found this problem on my code:
Hardcoded credentials (username / password) are visible to any person reading the source code.
If the resource protected by such hardcoded credentials is important, this may compromise system security.
With hardcoded credentials, change is difficult. If the target account is compromised, and the software
is deployed in production, a code change is needed, which forces a redeployment.
Please note that source code access is not always necessary: if an attacker has access to the JAR file,
he/she may dis-assembly it to recover the password in clear.
And it found this problem on my 3 querys:
public static final String CHECK_USER = "SELECT nome FROM utenti WHERE nome=? AND password=?";
public static final String INSERT_USER = "INSERT INTO utenti (nome, password) VALUES (?, ?)";
public static final String CHECK_USER_NAME = "SELECT nome FROM utenti WHERE nome=?";
How can I fix it? I made them in this way (picking up the info from the textfields) to make the login and check on the database.
Thanks to everyone!

I don't think your teacher is talking about those queries. I think he / she is talking about how your code creates its database connection. He / she has spotted that you have hardwired the user name and password for the database account into your Java code.
A simple solution for this is to read the database account details from a configuration file ... though now you have the problem of keeping the config file secure.
(Why do I think this? Because the text you quoted from your teacher talks about reading a password from the source code or a JAR file ... not from the database.)
For the record, it is also a bad idea to store passwords in the database. But that is not what your teacher is talking about.
Techniques for avoiding storing passwords in the database are more difficult. A typical solution is to create a seeded crypto-hash for the password, and store that in the database. But means that you can't recover the original password. If you need to do that, then things get even more "hairy" ... from a security perspective.

Related

NoSQL injection - java server

I am trying to create a java servlet with a NoSQL injection vulnerability. I've connected the servlet with MongoDB and check if the login info submitted by the user exists, I'm doing the next query:
String andQuery = "{$and: [{user: \""+u+"\"}, {password: \""+p+"\"}]}";
Where u is the user and p is the password given by the user.
For what I've seen this is correct, and the NoSQL injection should exist, bu I really dont kno how to prove it.
I've tried submitting with burp this:
username[$ne]=1&password[$ne]=1
But its not working, and when I check the content of u and p after I submitted that the content of both variables is null.
I dont have the servlet configured to receive json objects so I need a solition that doesn't imply send a json object with burp.
PD: I tryed also to insert something like this:
{\"$gt\":\"\" }
in the user and password fields but the result query is
{"$and": [{"user": "{\"$gt\":\"\" }"}, {"password": "{\"$gt\":\"\" }"}]}
I guess this doesn't work because the {"$gt":"" } is in quotes, ¿how can I do the servlet to be vulnarable and with which input it would be vulnerabel?

Picketlink: finding users with given role

I configured a JPA store and see users and roles getting added correctly to the db when I call the related picketlink (2.7.1) API's
My questions is this: how does one get a list of all users that have a given role?
I tried doing this using the following RelationshipQuery
RelationshipQuery<Grant> rq = relationshipManager.createRelationshipQuery(Grant.class);
rq.setParameter(Grant.ROLE, role);
List<Grant> grants = rq.getResultList()
But the resulting grant list contains a single assignment grant, that refers to the last user in the database that has that role.
I checked the example queries in the documentation and tests but found nothing that does what I want. I know the project is no longer active but am hoping to find a solution to this.
Found out that role data wasn't imported correctly from the old db. Once I fixed that the above code worked as expected.

BCrypt.checkpw not working (Java)

My web app uses BCrypt to encrypt user password and save it to MySQL (column data type: varchar(255))
BCrypt.hashpw(password, BCrypt.gensalt(15));
However, when the user logins, the BCrypt.checkpw fails to match the password that is the same as the one used in registration (before hashing).
boolean passwordMatch = BCrypt.checkpw(password, user.getPassword()); //false
I don't know what's happening. Does anyone have an idea where I should check?
I just found out that it doesn't seem having anything to do with BCrypt, because I tried to recompile my web app, and the login works, however, I don't understand why it requires a recompile though.
BCrypt.hashpw(password, BCrypt.gensalt(15));//this is when you insert
//********
boolean passwordMatch = BCrypt.checkpw( plainPassword , myPasswordOnDB);
(plainPassword is the String password and myPasswordOnDB is the encrypted password)
This is the right way of checking a password. If that doesn't work for you try making the mySQL column password char(60).

Why will following sql-statement not work with JDBC?

I am programming a basic database management system in java. When the user submits his username and password, the program will search in a database of the submitted data is correct:
result = stat.executeUpdate("SELECT username,password FROM DB" + "WHERE (username = '"+loginusr.getText()+"',password = '"+loginpwd.getText()+"')");
Apparently there is an error near the = sign. Can someone help figuring this out?
Thanks in advance
A couple of issues there.
First, you need a space before the WHERE:
result = stat.executeUpdate("SELECT username,password FROM DB" + "WHERE (username = '"+loginusr.getText()+"',password = '"+loginpwd.getText()+"')");
// Here ---------------------------------------------------------^
But the more fundamental issue is that you've left that code wide open to SQL injection attacks and failures. Use PreparedStatement, don't concatenate strings to put your parameters in. Here's a nice illustration of why:
From: http://xkcd.com/327/
And finally: It's not best practice to store passwords in a database. Instead, typically you store a cryptographic hash of the password, not the password itself (SHA-256 is one hashing technique, for instance). Then when the user is authenticating, you hash what they gave you as their password and compare it with the hash you have stored. That way, the password cannot be retrieved from the database.
Apart from the general advice not to use string concatenation for SQL queries, but parameters instead, there is a mistake in the source: …DB" + "WHERE… has no space.
Your text expands to:
SELECT username,password FROM DBWHERE (username = ...
You need to add a space in to your string and use AND rather than ,, e.g.:
result = stat.executeUpdate("SELECT username,password FROM DB " +
"WHERE (username = '"+loginusr.getText()+"' AND password = '"+loginpwd.getText()+"')");
However, bear in mind that if this is an example of real code, there are at least two major security issues that should also be addressed.

Getting all users with a Role in Liferay

I'm new to Liferay development in general, so feel free to point out if I'm going about stuff totally the wrong way.
I'm trying to get a DynamicQuery object of all users within a certain group (I'll use this object to further filter another query I'll do against the message board). The User interface seems to have a roleIds property that I might be able to use, since I already know the roleId I'm interested in. But I can't find the proper way to query if roleIds contains a certain value.
Any ideas on what I want to do?
PS: I would have the exact SQL query I could ask directly, but I'd rather use Liferay's own connection pool, without needing to do some weird ext project thingy.
You don't need a DynamicQuery. These are the methods you are looking for in the classes that Dirk points out:
long[] UserServiceUtil.getRoleUserIds(long roleId)
or
long[] UserLocalServiceUtil.getRoleUserIds(long roleId)
List<User> UserLocalServiceUtil.getRoleUsers(long roleId)
Remember that the methods in the classes XXXLocalServiceUtil are not checking the permissions of the current user.
EDIT: If you are looking for all users with a given role within a given community:
long companyId= _X_; //Perhaps CompanyThreadLocal.getCompanyId() if you don't have it anywhere else?
Role role=RoleLocalServiceUtil.getRole(companyId, "Example Role");
Group group=GroupLocalServiceUtil.getGroup(companyId, "Example Community");
List<UserGroupRole> userGroupRoles = UserGroupRoleLocalServiceUtil.
getUserGroupRolesByGroupAndRole(groupId, role.getRoleId());
for(UserGroupRole userGroupRole:userGroupRoles){
User oneUser=userGroupRole.getUser();
}
The easiest way to access liferays own objects is by using the XXXServiceUtil classes (e.g. RoleServiceUtil.getUserRoles(userId)). Thus you rarely have to deal with any SQL directly. Either the RoleServiceUtil or UserServiceUtil might have what you need.
The roles of an Organizations are stored in the table UserGroupRole, so if you want to get the owner of an Organization you must use the following code:
boolean isOrgOwner =
UserGroupRoleLocalServiceUtil.hasUserGroupRole(
usr.getUserId(),
this.currentOrganization.getGroupId(),
RoleConstants.ORGANIZATION_OWNER);
If you want to retrieve all the Organization Owners of an organization:
List<User> administrators = new LinkedList<>();
List<UserGroupRole> allOrganizationAdministrators =
UserGroupRoleLocalServiceUtil.getUserGroupRolesByGroupAndRole(
this.currentOrganization.getGroupId(), roleId);
for (UserGroupRole userGroupRoleTemp : allOrganizationAdministrators) {
administrators.add(userGroupRoleTemp.getUser());
}
Cheers!

Categories

Resources