java jdbi3 withHandle delete not updating the DB - java

I am using java JDBI3 to perform basic CRUD on mariaDB.
I am able to establish connection successfully.
The select * query from java works correctly.
jdbi.withHandle(handle -> handle.createQuery(
"SELECT * FROM users where email = :email;")
.bind("email", email)
);
Similarly when I try delete from it does not update the DB
jdbi.withHandle(handle -> {
return handle.createUpdate(
"DELETE FROM users WHERE email = :email;")
.bind("email", email)
.execute();
}
);
I tried to login in the sql shell and form there I am able to delete
DELETE FROM users WHERE email = 'dummy#email.com'
Can someone tell me what am I doing wrong?

You should not be using "createUpdate" method as per its documentation:
https://jdbi.org/apidocs/org/jdbi/v3/core/Handle.html
Create an Insert or Update statement which returns the number of rows
modified.
Instead, write
jdbi.withHandle(handle -> {
return handle.execute(
"DELETE FROM users WHERE email = :email",email);
});

Related

Sqlite-JDBC update with LIMIT clause?

I am trying to use the update query with the LIMIT clause using sqlite-JDBC.
Let's say there are 100 bob's in the table but I only want to update one of the records.
Sample code:
String name1 = "bob";
String name2 = "alice";
String updateSql = "update mytable set user = :name1 " +
"where user is :name2 " +
"limit 1";
try (Connection con = sql2o.open()) {
con.createQuery(updateSql)
.addParameter("bob", name1)
.addParameter("alice", name2)
.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
}
I get an error:
org.sql2o.Sql2oException: Error preparing statement - [SQLITE_ERROR] SQL error or missing database (near "limit": syntax error)
Using
sqlite-jdbc 3.31
sql2o 1.6 (easy database query library)
The flag:
SQLITE_ENABLE_UPDATE_DELETE_LIMIT
needs to be set to get the limit clause to work with the update query.
I know the SELECT method works with the LIMIT clause but I would need 2 queries to do this task; SELECT then UPDATE.
If there is no way to get LIMIT to work with UPDATE then I will just use the slightly more messy method of having a query and sub query to get things to work.
Maybe there is a way to get sqlite-JDBC to use an external sqlite engine outside of the integrated one, which has been compiled with the flag set.
Any help appreciated.
You can try this query instead:
UPDATE mytable SET user = :name1
WHERE ROWID = (SELECT MIN(ROWID)
FROM mytable
WHERE user = :name2);
ROWID is a special column available in all tables (unless you use WITHOUT ROWID)

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.

SQL Delete from two table in Oracle

I have to do remove the row (containing the userId) in the table "USERS". This is my query:
#SqlUpdate("delete from USERS where userId = :userId ")
void removeUser(#Bind("userId") String userId);
But first I want to remove that user from the table "USERS_DATA" (that is a daughter of USERS) which also contain the "userId". How can I do? I've tried this:
#SqlUpdate("delete from USERS_DATA where userId = :userId " +
" and delete from USERS where userId = :userId")
void removeUser(#Bind("userId") String userId);
but console tell me: java.sql.SQLSyntaxErrorException: ORA-00936: missing expression
Unlike some other RDBMS, Oracle does not allow you to pass two statements in the same SQL command (this helps to prevent SQL injection).
You can try using wrapping both queries in an anonymous PL/SLQ block:
BEGIN
delete from USERS_DATA where userId = :userId;
delete from USERS where userId = :userId;
END;
/
This will allow you to execute both DML statements together as they are part of the singular containing PL/SQL block.
Unfortunately, I am not familiar with that annotation syntax in Java so I cannot help you convert it to Java but I would guess at:
#SqlUpdate("BEGIN " +
"delete from USERS_DATA where userId = :userId; " +
"delete from USERS where userId = :userId; " +
"END;")
void removeUser(#Bind("userId") String userId);
Alternatively, you can create a procedure in Oracle:
CREATE OR REPLACE PROCEDURE delete_user(
in_userID USERS_DATA.USERID%TYPE
)
AS
BEGIN
DELETE FROM USERS_DATA WHERE userId = in_userId;
DELETE FROM USERS WHERE userId = in_userId;
END;
/
And you can then just call this procedure.

JPA NOT IN statement

I have a app that uses MySQL, JPA with EclipseLink.
I'm trying to get from the DB the collection of User flagged as "ACTIVE" and that are not already in a List already loaded in the application.
That is my method:
public List<User> findAllButUsers(List<User> users) {
List<User> list = null;
Query query = em.createQuery("SELECT u FROM User u WHERE u NOT IN :users AND u.status = :status");
query.setParameter("status", "ACTIVE");
query.setParameter("users", users);
list = query.getResultList();
return list;
}
And the Log from server gives me that:
Fine: SELECT iduser, create_time, email, name, password, salt, status FROM user WHERE ((iduser NOT IN (?)) AND (status = ?))
bind => [com.wa.gp.jpa.entities.User[ iduser=2 ], ACTIVE]
From the bind => [com.wa.gp.jpa.entities.User[ iduser=2 ], ACTIVE] shows me that instead of binding the id it passes the value from User.toString method thus resulting in a Collection that includes the users passed. I thought it would work just sending the object to JPA and it would figure out the iduser by itself.
I don't know if it is a expected behavior, looks to me it is. How can I just make that query without having to change the valor from tostring in User? Do I have to instead of giving the List of Users just pass a List of the Ids? If that is the case I just became said.
Thanks

Categories

Resources