SQL Injection and possible attacks - java

Hi I have the following query which is part of a java class. I just want to know what are the possible attacks possible with the SQL Injection. How an attacker can inject queries? What are sample queries in this case that can be used to gain access to the database?
String query = ("SELECT username, password, admin FROM users
WHERE " + "username='" + username + "' AND password='" +
password + "'");
ResultSet rs = st.executeQuery(query);
// Entry in the result set means the query was successful and
//the user is a valid user
if (rs.next()) {
username = rs.getString(1);
isAdmin = rs.getBoolean(3);
I think this is a possible way of attack also by putting username as abc';# since anything after # will be considered as a comment in SQL. What others think about it?
I want to know what the attacker will be entering in the username box and password box of the HTML page to gain access as an administrator. Assuming the job of the above java class is to process the request of the users's input from a HTML page by querying a database.

basically it works like this https://xkcd.com/327/
what I do is assuming, that everything a user inputs is a threat, so I would save everything to variables like usUsername, where "us" means unsafe.
After that I check every "us"-variable for injections, what results in sUsername (s means safe). So when I build a query I can only use s-varaibles and should be safe in most cases.
This idea is totally taken from here: http://www.joelonsoftware.com/articles/Wrong.html

Based on this code you could do ANYTHING you want by manipulating the values of the username or password text sent to the query.
The only constraint is the level of permission of the user account executing the query. If it was a sysadmin, you could delete everything. If it's SQL Server and xp_cmdshell is enabled, you could format the hard drive of the SQL server.
SQL Injection is one of those things where if you can do something you can pretty much do anything.
Look into the Havij tool, that is a security research tool that can demonstrate the power of SQLi.

You can not do that. username and password can be replaced by anything leading to all types of queries. You must use a prepared statement to provide username and password

Entering the following values for password would add a row to the result set containing the values 'admin', 'dummy', 1 for username, password, and admin, respectively:
' AND 1=0 UNION SELECT 'admin', 'dummy', admin FROM users WHERE admin = 1 AND '1'='1
The resulting query would look like:
SELECT username, password, admin FROM users
WHERE username='dummy' AND password='' AND 1=0 UNION SELECT 'admin', 'dummy', admin FROM users WHERE admin = 1 AND '1'='1'
The first SELECT would return no result as 1=0 is false for each record. But the second, injected SELECT would return all records where admin=1 is true and replaces the original values for username and password with admin and dummy, respectively.
You should use prepared statements and pass the values as parameters on execution.

Related

Including static values in SQL query

I'm testing SQL injection in my lab and need to combine two SQL queries using UNION to bypass authentication, so I would like to know if there is a way to set static values in second query, so that my JAVA code will check will only check for the user password I send as static password : The SQL Query should be like this :
SELECT * FROM users WHERE user = 'user1' UNION SELECT user AS
user1, password AS password FROM users ;'
My JAVA code reports an error :
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to
use near
First, eliminate the use of SELECT * to make sure both queries return the same number of columns. Then you can hard code your static values in the second query.
SELECT user, password
FROM users
WHERE user = 'user1'
UNION
SELECT 'user', 'password';
Using union
You must select the corresponding number type of column eg:
SELECT user, password
FROM users
WHERE user = 'user1'
UNION
SELECT 'user', 'password'
;

Lookup and extract db value based on input (Java & SQL Server)

New to java.
I am attempting to write a class that will input a username, run a query on the username to find the ID, and subsequently use that ID in "where clauses" on all my other classes.
This is the statement that I execute (which will only ever return a recordset of a single row):
String sqlStatement = "SELECT AccountHolderId, Passcode from CIS4720.DBO.AccountHolder " +
"where Username = '" + logonName + "'";
Here is my attempt at extracting the ID via the username...
while (rset.next())
{
if(rset.getInt("Username")==logonName){
int whosOnFirst = rset.getInt("AccountHolderId");
}
I saw another answer on the forum that says you can't assign database values to variables. If that is the case, what is a better strategy?
(Also, I realize I'm not parameterizing, but I'd like to get this working before fixing that issue. This is for a course assignment so I am not worried about hack attacks).
P. S. Thanks I fixed the double equals sign (and the extra parenthesis) in the code above.
Here are some comments about the code:
rset.getInt("Username") will get the column Username from the result but it also looks for an Integer column because of getInt. You are not selecting that column in the sql statement so will error out.
If you select it and get a string, use .equals() instead of == to compare string. Also, one = is assignment and == is comparison.
You can use getString to read Strings from the result set.
You don't need to check the username and match it since your query should return exactly that user's data so I would remove the if condition entirely and just have the getInt line there.

how do i look for duplicate values (username,password) in login database in java?

So, i have a login form that gets Username and Password. The data for these are stored in a Postgre table i made called useraccounts.
Is there a way to send an error whenever a user inputs a duplicate data in the login form?
For example, if my useraccounts has
username || password
admin pass
guest password
admin pass
how do i just show an error that you cant log in,if you want to enter as admin?
I think you should use follow behavior.
Column "UserName" should have type citext. It give you a simple search.
Execute query
Select username from users where username='user name'
or
Select username from users where username=?
if you can use prepared statement.
Than you check a result of query execution. If ResultSet is not empty this mean that user with name "user name" already exist and you can provide error.

How can I retrieve two fields of a table in Mysql with Java?

I have a ClientsTable like that :
firstName lastName address idNumber userName password
| | | | |
david bowie here 123 mick jagger
chuck norris there 456 steven seagal
I want to get both the userName and the password of each row and verify it with the given parameters of my method :
public Person verifyClientExists(String username,String password) throws SQLException
{
ResultSet results = this.m_statement.executeQuery("SELECT `userName` FROM `ClientsTable`");
while (results.next() == true)
{
// here I want to compare the retrieved data from
// mysql with the "username" and "password" given in the prototype
}
return null;
}
But with my current query I can only get one field .
How can I retrieve two fields?
Why not use
select username, password from clientstable
? And then your ResultSet interrogation is:
String username = results.getString("username");
String password = results.getString("password");
See the JDBC tutorial page on ResultSets. Note that I ask for the results by column name. It's fractionally more robust than by asking for them by index (number). If I change the SQL statement (reorder query parameters) then the correct columns are still returned.
I hope you're not storing cleartext passwords in those tables, btw! See here for more info on hashing and salts.
Change your query to:
SELECT `userName`, `password` FROM `ClientsTable`
First, I would suggest using the APIs to build queries, and not execute raw queries (take a look here).
But to answer your question - if you want to get also the password use:
ResultSet results = this.m_statement.executeQuery("SELECT `userName`, `password` FROM `ClientsTable`");
alternatively, you can check the number of records from the result:
SELECT COUNT(*)
FROM `ClientsTable`
WHERE userName = 'userHere' AND
password = 'passHere'
the result here would be 0 and 1 only :) because I assume that the username is unique.
but if you want to retrieve the username and the password, just select the two columns in your query.
SELECT `userName`, `password`
FROM `ClientsTable`
You can ask for more fields like this: SELECT userName, password FROM ClientsTable
Then use resultSet.getString(1) for userName and resultSet.getString(2) for password
Change your sql to "SELECT userName ,password FROM ClientsTable
Now you can use the resultset object and fetch the values
results.getString(1)
results.getString(2)
or you can retrieve using the fieldName
results.getString("userName");
results.getString("password");
Your query is wrong. Your query should be like :-
SELECT EMP_NAME,EMP_PASSWORD FROM EMP_DETAILS TABLE;
Its quite simple to retrieve not only 2 field but also any number of field.

SQL injection on PostgreSQL

My clienet(android) sends user details in the user form and my servlet just enters those details into to the database(postgre sql). I tried to give to do a sql injection attack by giving ;DELETE FROM tbl_name; in the username field.
But postgresql just treats it as a value and enters it as the username. How do I do the SQLINjection attack. (I have not done any sort of checking in the postgre sql or the servlet).Does it mean that postgresql is SQLInjection attack resistant?
I am using the following statements to insert the data:
String insert ="insert into userdetail(username,id,sno) values('"+username+"','"+userid+"','"+no+"')";
Statement stmt = conn.createStatement();
stmt.executeUpdate(insert);
The username contains ;DELETE FROM userdetail;.
I have tried the following also:
');DELETE FROM userdetail;
But it fives the following error:
org.postgresql.util.PSQLException: ERROR: unterminat
ed quoted string at or near "');"
Position: 1
I have also tried this:
','',');DELETE FROM userdetail;
This gives the following error:
17:36:46,828 INFO [STDOUT] org.postgresql.util.PSQLException: ERROR: unterminat
ed quoted string at or near "''');"
Position: 38
but does not delete the records of the table. How do I make it delete the tables records?
The key trick is that the complete statement string must
do something innovative
be still valid SQL
So far the answers have omitted the second part. But an invalid SQL statement will abort the transaction and hence most likely does nothing at all. If you set autoCommit to true that attack may be easier.
But this string should to the trick in a "clean" way:
foo', '42', '42'); delete from userdetail; --
Note: The resulting string is this (line breaks only for better reading):
insert into userdetail(username,id,sno) values('foo', '42', '42');
delete from userdetail;
-- ','21','21')
Both the INSERT part is complete and correct (assuming no unique index collisions of course) and also the DELETE is correct. The potentially offending rest is masked by the trailing SQL comment --.
hat type of attack that you are describing - even if you get the use of single quotes "correct" - will not work with PostgreSQL
It does not work because the JDBC driver does not allow to run more than one statement in a single Statement.execute() call.
It will throw an error ("invalid character" pointing to the ;)
(Sorry, this is only true for Oracle)
There are other scenarios that would work with a badly written application.
Assuming the application is checking the username/password like this (note that this is a very simplified example!)
String sql = "SELECT count(*) FROM users WHERE username = '";
sql += username;
sql += "' AND password = '";
sql += pwd;
sql += "'"
then a possible attack could be to enter the value:
' or 1=1 or '' = '
into the password field.
This would wind up with the following generated SQL
SELECT count(*) FROM users WHERE username = 'arthur'
AND password = '' or 1=1 or ''=''
Which would always be true and one could login without a password.
Try ', '', '');DELETE FROM tbl_name; to delete your table.
In simplest case, you can give ' as user name and your server should give you an error.
Besides, there is no SQL injection resistant database because SQL injection happens because of poorly coded server-side (CGI) script and not because of database weaknesses.

Categories

Resources