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.
Related
I have a java swing application which starts with a login page and should take admin to the dashboard if the login is authenticated. As there is just 1 admin, so there is just 1 username and password combination.
Right now, I am just inserting username and password to the sql table using a simple insert query.
I am new at this so I don't know how to go about this
create table login (
Emp_id INT AUTO_INCREMENT PRIMARY KEY,
Emp_Fname VARCHAR(50),
Emp_Lname VARCHAR(50),
Username VARCHAR(50),
Password VARCHAR(50)
);
insert into login (Emp_id, Emp_Fname, Emp_Lname, Username, Password) values (1, 'TestFName', 'TestLName', 'Test', 'Test');
Instead of storing passwords in plain text, I want it encrypted or hash.
I am currently typing from my phone so forgive me. It seems like u want your password to look like: eive29ceic28e8c38d9h3ce9h instead of "password123"
You can use something like SHA-1, which have an integration in java with SHA256 and SHA512. Both of which can be found after a quick Google search. I personally used them in a project but ran recursively this method 100 times using the result from one round as the input for the next. Then I extended the length of the string by using this scheme: password + password backwards + password + password. In my case the password got 4x512 bits long and seemed relatively secure.
After that I saved it to a file and every time I want to login, I take the input and encrypt it and then compare it to my password in my file. If they match you're in. I know that you can crack sha-1 opens it brute force. If you want something different try bcrypt, pbkdf2 or argon2.
I would like to give you links but that's hard on mobile. I hope this works iut for you. Otherwise I will comment tomorrow morning
Edit: look into your comments there is a link to the algorithm I meant. Just put it in a for loop 100 times...
I am new. Trying to do a database retrieve demo to login a system, here is my function code:
I will call goLogin function and pass in the input id and password for validation and I will also get all the id from Database for checking purpose. After ID is correct, only go check the password.
public void goLogin(String id, String pass){
String[99] allID = getAllIDFromDB();
for(int i=0;i<allID.length;i++){
if(allID[i]==id){
String passwordDB = getPasswordFromDB(id);
if(pass==password){
System.out.println("Correct Password");
}else{
System.out.println("Wrong Password");
}
}
}
My peers say I was using too much if else and I can shorten the code and make the program better, and I faced some issue on looping for example when ID and Password are correct, the program will still continue the loop.
Is there any suggestion to make this function better?
First of all, Why retrieve all the user IDs from the database instead make sql query to retrieve the row of this user based on this id.
something like this:
Select * from `users` where id = {id};
And if you want to stop looping a wrong password was found, add break in the else scope.
In my opinion, the main issue of your program is your logic to implement the Login Function.
Login Function implementation can be implemented with various pattern, Based on your program code I will assume you just want a Most Basic Login Function that allow the program to do validation on user input ID and Password.
Actually, this Basic validation can be done in your Database Query. You can just take the user input ID and Password and let Database Query to do filtering and determine if the user input ID and Password is valid or invalid.
First use this Query:
Select DATABASEID From Database Where DATABASEID=inputID and DATABASEPASSWORD=inputPassword;
Java Code:
public void goLogin(String id, String pass){
// Since i changed the Query, you need to pass in the ID and Password to let the Query to filtering
String DatabaseID = getIDFromDB(id, pass);
// Simple Logic, If DatabaseID have value which mean the ID and Password is correct
// Because the Database Query will return null if the ID and Password is Wrong
if(DatabaseID!=null){
System.out.println("ID and Password is Correct.");
}else{
System.out.println("ID or Password is Incorrect.");
}
}
This Logic is very simple, but also come with some drawback, the only Advantage Compare to your code are:
Still able to do basic validation on User Input ID and Password.
Remove for loop and other unnecessary if else.
Only access database for once.
Hope this would help.
Yes, you could even do:
Select * from `users` where id = {id} and password = {password}
Also, to compare Strings in Java, you should use string1.equals(string2), not the == operator.
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.
I need to parse a query which a user enters, say in a text box, and then what I need, is that I want to encrypt all the values in query leaving the query keywords. To convert it into an equivalent query that can be performed on an encrypted database.
Such as,
select name from employee where salary = 10000
I need an equivalent query as,
select name_enc from employee_enc where salary_enc = 10000_enc
where name_enc,employee_enc, salary_enc and 10000_enc are the encrypted values of name, employee, salary and 10000. I need to do this in java and the the database I'm using is MySQL Server where the table Employee is already encrypted.
Please provide any necessary help. Thanks in advance.
You may want to consider using code from Alibaba's Druid project. Although designed as a sophisticated connection pooling library, this project supports a very advanced parser and AST for ANSI SQL and non-ANSI dialects such as MySQL, Oracle, SQL Server, etc. The project is open source and bears the very liberal Apache License Version 2.0.
The main entry points into this part of the library is SQLUtils.java. You can use values returned from SQLUtils.parseStatements to access a typed model of the statements:
List<SQLStatement> statements = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
for (SQLStatement statement : statements) {
if (statement instanceof SQLSelectStatement) {
SQLSelectStatement createTable = (SQLSelectStatement) statement;
// Use methods like: createTable.getSelect().getQuery().
}
}
If you don't need to do it manually use SQL's included encryption and encoding operations.
If you need to do it manually split your SQL query string by spaces and ignore SQL key words as you loop to encrypt. Remember to encode your cipher results with base 64 or hex to ensure data integrity.
private String encryptSQLQuery(String plainSQLQuery){
StringBuilder cipherQuery = new StringBuilder();
String plainQuery = plainSQLQuery;
String[] splitQuery = plainQuery.split("\\s+");
for(String queryWord : splitQuery){
if(!isSQLKeyWord(queryWord))
queryWord = cryptoObject.encryptAndEncode(queryWord);
cipherQuery.append(queryWord);
cipherQuery.append(" ");
}
return cipherQuery.toString();
}
Note that you will have to implement the isSQLKeyWord() and CryptoObject.encryptAndEncode() methods.
I just stumbled upon some SQL code of a colleague (we have a "dont fix it, if it aint broke policy"), for a login process.
The name variable is delivered by an input field from a JSP.
//BAD CODING ALERT: DONT USE THIS CRAPPY CODE, YOU NAUGHTY COPY PASTERS!
Query q = em.createQuery("select object(u) from User as u where u.name = '" + name + "'");
With no sanitation at all on the name variable except of server side validating on some Illegal characters: <>"'%;() (mind that that is single and double quotes)
Can this be exploited? And if yes, how so?
If it wasnt for the single and double quotes, one could do something like: blah' OR 'x'='x
You should NEVER EVER create query by string concatenation. use query.setParameter("paramName",paramValue);
so it would be something like that
Query q = em.createQuery("select object(u) from User as u where u.name =:name");
q.setParameter("name", "O'Reilly")
no SQLInjections possible because of escaping values;
Answering my own question... it is safe, however not practical as allready stated by myself.
Before downvoting this, READ the question. Or give an exploit example otherwise.