I am trying to log in with a name and an ID in a JTextField after a ButtonClick. After the first log in all the users are stored in the database.
What I am trying to do is: If the user is already stored in the database I want to show the message ("Welcome back") but what I got at the moment is "Duplicate entry '11' for key 'PRIMARY'. I want to "ignrore that" because if a user is stored in the database it should have the possibility to log in again and continue for the next page. And if a user is new, I will show a JOptionPane ("Welcome new user")
What I tried so far:
JOptionPane.showMessageDialog(null,"already exist");
}
String query1 = "SELECT * FROM user";
PreparedStatement pst1 = con.prepareStatement(query1);
ResultSet r1= pst1.executeQuery();
if(....)JOptionPane.showMessageDialog(null,"...");}
else if(r1.next()) {
if (r1.getString("ID").equals(txtFieldID.getText())) {
Thx all in advance.
You should first execute a query to validate that the ID already exists in database so in that case you'll only get one result: SELECT COUNT(ID) FROM USERS WHERE ID = ?. If the result of that query returns a value greater than 0 then the user exists and you show the message.
You should't query the whole table and then iterate each row to do that kind of validation.
Related
I have a web application that I am trying to "break".There's a login page that requires username and password input. Let's say I have a table Auser that stores username's info in MySQL.
When I hit Login after keying the credentials,it executes this line of code:
String sql = "select object(o) from Auser as o where ausername='" + username + "'";
Now, I know not using preparedStatement makes SQL query vulnerable to SQL injection and I want to perform such a stunt. I created a dummy table called test for the purpose of able to drop this table via the injection command.
I tried various ways like in my username input(root is the username):
root` DROP TABLE test;
And it didn't work. Is there a way to make my injection successful?
Update:
Just extra info, my username column is VARCHAR(255) and my method for getting the username is below:
public Auser get(String username, boolean moreInfo) {
try {
Auser u = null;
String sql = "select object(o) from Auser as o where ausername='" + username + "'";
List resList = em.createQuery(sql).getResultList();
if (resList == null) { // null check for sql query / library error
msg = CoreUtil.wrapMsg(CoreUtil.FUNC_ERROR,
this.getClass().getName(), "get[" + username + "]", "query error AUSER.");
} else if (resList.isEmpty()) {
msg = "User " + username + " not found.";
} else {
u = (Auser) resList.get(0);
}
return u;
} catch (Exception e) {
msg = CoreUtil.wrapMsg(CoreUtil.FUNC_ERROR,
this.getClass().getName(), "get[" + username + "]", e.getMessage());
return null;
}
}
Seems every solution, I tried keeps throwing IllegalArgumetnException and the table still remains.I just want to exploit the vulnerabilities of my program,it can be any kind of injection whether dropping a table, returning all users info,etc.
The EntityManager has some (very) basic protection built in that won't run more than one command in the same SQL statement.
This will protect you from Robert'); DROP TABLE Students; --, but it won't protect from attackers trying to expand/alter the one query that's being run.
For example, in your code an attacker could get the details of another user by entering the username ' OR 1 = 1 --; This would make the SQL string being executed
select object(o) from Auser as o where ausername='' OR 1 = 1 --'
which will select every user in the table (note that the -- at the end of the input will comment out everything after the injected code), and your method will return the first user in the result list This will potentially give the attacker details about another user that they should not have access to. If the first account is an administrator account then they may also have access they should not have.
An attacker can also learn the structure of the table this way - they can try strings like ' and IS_ADMIN = IS_ADMIN --, or ' OR ID = 0 --. If they try enough of these (and attacks like this can be easily automated) they will find valid column names when the query doesn't throw an error. They can potentially then make a more targeted injection attack to gain access to an admin account.
They might also learn things from the error message returned from a failed attempt, such as the DB platform, which can make attacks easier.
String sql = "select object(o) from Auser as o where ausername='" + username + "'";
If you want to delete the test table
username = "x'; DROP TABLE test AND '1'='1"
If you want to see all fields of all ausers entries
username = "x' OR '1'='1"
I created an AddressBook GUI application with Insert, Update, Delete, Search, and Print functions. It connects to my access database table which contains four tables(names, addresses, phoneNumbers, and emailAddresses)
So far everything is working except when I try to search new input I just inserted into the table. If I search records I placed directly into access it works.
I THINK I narrowed down the problem but don't know how to fix it. When I insert new records into my table the names table creates a new primary key for that record but the rest of the tables don't, they only create a new foreign key number. Since my search is based on inner joining the id's I'm guessing my problem lies here but I'm not sure.
Here Is my Search Code
if (e.getActionCommand().equals("Search")){
JFrame mini = new JFrame();
// Gets user input. If user presses Cancel, 'name' will be null
String first = JOptionPane.showInputDialog(mini,"Enter first name:");
String last = JOptionPane.showInputDialog(mini, "Enter last name:");
try{
resultSet = statement.executeQuery( "SELECT * FROM ((names INNER JOIN addresses
ON names.personID = addresses.addressID)INNER JOIN phoneNumbers
ON names.personID = phoneNumbers.phoneID) INNER JOIN emailAddresses
ON names.personID = emailAddresses.emailID
WHERE lastName LIKE '%" + last + "%' AND firstName LIKE '%" + first+"%'");
resultSet.next();
jTextField1.setText(resultSet.getString("firstName"));
jTextField2.setText(resultSet.getString("lastName"));
jTextField3.setText(resultSet.getString("address1"));
jTextField4.setText(resultSet.getString("address2"));
jTextField5.setText(resultSet.getString("city"));
jTextField6.setText(resultSet.getString("state"));
jTextField7.setText(resultSet.getString("zipcode"));
jTextField8.setText(resultSet.getString("phoneNumber"));
jTextField9.setText(resultSet.getString("emailAddress"));
jTextField10.setText(resultSet.getString("personID"));
jTextField10.setEditable(false);
} catch(SQLException sqlException) {
JOptionPane.showMessageDialog(null, sqlException.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
}
}
Access uses * as the wildcard character, not %
I came across a problem with going through a ResultSet I'm generating from my MySQL db. My query should return at most one row per table (I'm looping through several tables searching by employee number). I've entered data in some of the tables; but my test o/p says that the resultset contains 0 rows and doesn't go through the ResultSet at all. The o/p line it's supposed to print never appears. It was in a while loop before I realised that it'd be returning at most one row, at which point I just swapped the while(rs.next()) for an if(rs.first()). Still no luck. Any suggestions?
My code looks like this:
try
{
rsTablesList = stmt.executeQuery("show tables;");
while(rsTablesList.next())
{
String tableName = rsTablesList.getString(1);
//checking if that table is a non-event table; loop is skipped in such a case
if(tableName.equalsIgnoreCase("emp"))
{
System.out.println("NOT IN EMP");
continue;
}
System.out.println("i'm in " + tableName); //tells us which table we're in
int checkEmpno = Integer.parseInt(empNoLbl.getText()); //search key
Statement s = con.createStatement();
query = "select 'eventname','lastrenewaldate', 'expdate' from " + tableName + " where 'empno'=" + checkEmpno + ";"; // eventname,
System.out.println("query is \n\t" + query + "");
rsEventDetails = s.executeQuery(query) ;
System.out.println("query executed\n");
//next two lines for the number of rows
rsEventDetails.last();
System.out.println("no. of rows is " + rsEventDetails.getRow()+ "\n\n");
if(rsEventDetails.first())
{
System.out.println("inside the if");
// i will add the row now
System.out.println("i will add the row now");
// cdTableModel.addRow(new Object[] {evtname,lastRenewalDate,expiryDate});
}
}
}
My output looks like this:
I'm in crm
query is
select 'eventname','lastrenewaldate', 'expdate' from crm where 'empno'=17;
query executed
no. of rows is 0
I'm in dgr
query is
select 'eventname','lastrenewaldate', 'expdate' from dgr where 'empno'=17;
query executed
no. of rows is 0
NOT IN EMP
I'm in eng_prof
query is
select 'eventname','lastrenewaldate', 'expdate' from eng_prof where 'empno'=17;
query executed
no. of rows is 0
I'm in frtol
query is
select 'eventname','lastrenewaldate', 'expdate' from frtol where 'empno'=17;
query executed
no. of rows is 0
(and so on, upto 17 tables.)
The '17' in the query is the empno that I've pulled from the user.
The thing is that I've already entered data in the first two tables, crm and dgr. The same query in the command line interface works; this morning, I tried the program out and it returned data for the one table that had data in it (crm). The next time onwards, nothing.
Context: I'm working on a school project to create some software for my dad's office, it'll help them organise the training etc schedules for the employees. (a little like Google Calendar I guess.) I'm using Netbeans and Mysql on Linux Mint. There are about 17 tables in the database. The user selects an employee name and the program searches for all entries in the database that correspond to an 'event' (my generic name for a test/training/other required event) and puts them into a JTable.
The single quotes around the column names and table name in the creation of the query seem to have caused the problem. On changing them to backticks, retrieval works fine and the data comes in as expected.
Thank you, #juergend (especially for the nice explanation) and #nailgun!
I am trying to select data from my db, but instead of getting a certain field I get "".
My table name is locations and it's look like this:
id - int,
location - varchar and time - timestamp.
I would like to select the last location based on the time, here is my code:
this.select = this.conn.createStatement();
ResultSet result = select.executeQuery("SELECT location FROM locations ORDER BY time DESC Limit 1");
result.next();
System.out.println(result.getString(1));
I remind you the output is "";
To identify the column in your resultSet you can use:
result.getString("location");
did u try ?
System.out.println(result.getString(0));
Current I am working on a hospital management system project. I have two tables doctor and patient and have made a link table Visits between them. Primary Keys of doctor and patient tables respectively are foreign keys of the Visits table. I am able to update the doctors table from my code. Whenever a record is inserted into the patients table, the doctor table is checked to find out whether the allocated doctor exists or not, if doctor exists and insertion is made into the visits table. For this I have created a trigger on Patients Table. Now whenever I try to register patients, the patients table gets updated but the code throws a MySQLException with message "Column Count Does Not Match Value Count At Row 1".
Code
this.stmt=this.mycon.createStatement();
String query_add_patient="insert into patients values ('"+nic+"','"+name+"','"+address+"','"+city+"',"+age+",'"+dob+"','"+telephone+"');";
String query_select_employees="select * from employees where employee_type='Doctor' and employee_qualification='"+doctor+"'";
ResultSet rs=this.stmt.executeQuery(query_select_employees);
if(!rs.next()) {
JOptionPane.showMessageDialog(this, "This Doctor is not available in this facility!!!","Admin Error",JOptionPane.ERROR_MESSAGE);
return false;
}
rs.first();
String pattern = "yyyy-m-d";
SimpleDateFormat format = new SimpleDateFormat(pattern);
String enic=rs.getString("employee_nic");
System.out.println(enic);
String query="insert into Visits (patient_nic,employee_nic) values ("+nic+","+enic+")";
this.stmt.executeUpdate(query_add_patient);
closeConnection();
openConnection();
this.stmt=mycon.createStatement();
this.stmt.executeUpdate(query);
return true;
Here the statement "insert into visits" causes the problem. I tried to close and open the connection again but that did not work. The structure for my visits table is
Visits
patient_nic (varchar(45)) FK --> patient.patient_nic
employee_nic (varchar(45)) FK --> employee-->employee_nic
Make Sure the Column Names Each Have a Matching Value and Vice Versa.
E.g
Good
$query = "INSERT INTO table (first_name, last_name)
VALUES(Mr,Kyaw)";
Bad
$query = "INSERT INTO table (first_name, last_name)
VALUES(Mr,Kyaw,Thu)"; //can give Column Count Does Not Match Value Count At Row 1 exception