How can I search new inserts in my access database? - java

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 %

Related

java-How to perform SQL injection for testing purposes?

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"

Java- check if id already exists in database

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.

PreparedStatement for reading temporary parameter

I am trying to read a temporary variable created from my MySql query as follows:
String name = "";
selectQuery = "select (select "
+ "CONCAT(s.firstname,\" \",s.surname) "
+ "AS name) "
+ "from student s, marks m where m.grade = 'fail'";
try{
pstmt = con.prepareStatement(selectQuery);
rs = pstmt.executeQuery(selectQuery);
int count = 0;
while(rs.next()){
name = rs.getString("name");
System.out.println(++count+". "+name);
}
rs.close();
pstmt.close();
}catch(Exception e){
e.printStackTrace();
}
I get SQLException as column 'name' not found. When I run the query in MySql server it runs fine.
In order for the alias to apply, it must be places outside the nested query's parenthesis, not inside it. However, you could just drop it altogether and just use the concat call directly in the select list.
Two more side notes:
Implicit joins (i.e., placing more than one table in the from list) have been deprecated for quite a while. It's considered a better practice to use explicit joins.
Regardless of the joining syntax you're using, you're missing the join condition.
Using concat_ws instead of concat may save you some hassle with handling the white space yourself.
To make a long story short:
select CONCAT_WS(' ', s.firstname, s.surname) AS name
FROM student s
JOIN marks m ON s.id = m.student_id
WHERE m.grade = 'fail'

Java cast to object changing other object

for (int i = 0; i < info.size(); i++) {
User b = (User) info.get(i);
rs = stmt.executeQuery("Select ARTIST,TITLE from SONGS WHERE ID = (SELECT ID from USERS WHERE USERNAME = " + "'" + b.Username + "'" + ")");
while (rs.next()) {
String artist = rs.getString("ARTIST");
String title = rs.getString("TITLE");
b.Songs.add(artist + "-" + title);
}
System.out.println(b.getSongs());
}
so this is my code which contains an array of users (info array) each of which have an array called songs which stores each song they own. I want to select the users songs form the song DB using their username which works fine, then add it to that users array.
However when I run the code this happens:
The info array has 2 users in it.
I get the first user 'Tim'
Get the songs he has: "Queen - We will rock you" and add it to his array, works fine.
Then loop and the next user is selected, but when I add to his array it contains the Queen song, then his songs.
I'm not sure how they are being added to the 2nd users songs array, the SQL works fine and only selects that users songs, but some how b.songs from the previous user is passed into the next user?
Could you be joining on the wrong column?
Select ...from SONGS WHERE ID = (SELECT ID from USERS where ...)
Seems wrong, that SONGS.ID is the ID of the user.
Shouldn't it be
Select ...from SONGS WHERE USER_ID = (SELECT ID from USERS where ...)
?
Also, die to the way you construct the query string, note that your code will fail if username contains the ' character.
Moreover, it's vulnerable to SQL Injection - a serious security threat.

Mysql JDBC - not entering ResultSet + incorrect no. of rows

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!

Categories

Resources