Not able to retrieve record using eachRow method - mysql

I am using below groovy code to select a row with a given username and password from mysql db.
For example,
I am searching for below user. Password is stored in db as a SHA1 hashed password.
Name - test7
password - {SHA}01132E914B722741CC3823D0BEACB8364EEAC376
Below is the groovy code which is trying to retrieve the record and failing as I am not able to fetch the record.I suspect the sql query constructed is wrong. SecurityUtil class is just decrypting and returning a plaintext password back as a positional parameter to the query. We are
using the sha1 method of mysql to generate the hash and prefix with string {SHA1} and then trying to retrieve the record.
sql.eachRow("SELECT id FROM users WHERE userName = ? AND password =CONCAT({SHA1},sha1(?))", [username, SecurityUtil.decrypt(password)]) {
authId = String.valueOf(it.id)
}

Welp if SQL doesn't want to play do it in Groovy. Using GStrings you get the same protection as prepared calls so no SQL Injection issues, and you can more easily do groovy operations:
sql.eachRow("SELECT id FROM users WHERE userName = ${userName} and password = ${'{SHA}' + SecurityUtil.decrypt(password)}") {
authId = String.valueOf( it.id )
}
The prepared statement syntax route:
sql.eachRow("SELECT id FROM users WHERE userName = ? and password = ?", [username, "{SHA}${SecurityUtil.descrypt(password)}"]) {
authId = String.valueOf( it.id )
}

sql.eachRow("SELECT id FROM users WHERE userName = ? AND password =CONCAT('{SHA1}',sha1(?))", [username, SecurityUtil.decrypt(password)]) {
authId = String.valueOf(it.id)
}
You may need to put the {SHA} in quotes for use in the concat operator.

Related

why my else cannoot execute while the statement is else?

I want to create a login page script with the username and password as the data account from db. n then when my input is doesn't match the else didn't execute while username and password is did not exist in db. so what should i do to fix this. any somebody help me please
def logindb():
print ("=="*15+"\nPlease insert your username and password.")
username = input ("Username : ")
password = input ("Password : ")
cursor.execute(f"SELECT * FROM data WHERE username='{username}' and password='{password}'")
result = cursor.fetchall()
for i in result:
if (i[0]) == username and (i[1]) == password:
print ("=="*15+"\n\tLogin Success.\n"+"=="*15)
else:
print ("=="*15+"\nUsername or password is wrong.\n"+"=="*15)
In your code snippet, the statement can NEVER be else!
You query for a database entries matching username and password. For every entry (with the matching username and password) you again check if these credentials are correct.
I guess what you want, is to check if there are records found.
Something like this:
result = cursor.fetchall()
if (len(result) > 0):
print ("=="*15+"\n\tLogin Success.\n"+"=="*15)
else:
print ("=="*15+"\nUsername or password is wrong.\n"+"=="*15)
Side note: you really should hash the password instead of saving it as plain text in the database.
Try changing:
cursor.execute(f"SELECT * FROM data WHERE username='{username}' and password='{password}'")
To:
cursor.execute(f"SELECT username, password FROM data WHERE username='{username}' and password='{password}'")
You're selecting ALL* columns, and if your 0 index column is not username, and your 1 index column is not password, your query result will not match up your submitted username and password.
if (i[0]) == username and (i[1]) == password:
It's also not a good idea to run your SELECT statements wide open if you don't need to. Retrieve only the columns explicitly that you need to retrieve.
You should really use a parameterized query.
But if you are going to use this method of data retrieval then I would go one step further then Griv's answer
cursor.execute(f"SELECT userid FROM data WHERE username='{username}' and password='{password}'")
I would never fetch the username or password. Instead, check for its existence by fetching the primary key of the table.
Then check if that value is null or not.
I am not familiar with python, I assume the f"SELECT is not a typo

Qt Checking Login using Database

I am using qt to create a user login. I am using Sqlite as my database and am stuck for some reason it is not working properly. I was able to corectly bypass the login screen only when typing in the first row from the database. Any other user cannot log in (row 2, 3,4 ... in database). I have been reading all kinds of posts for the past days and have not come to a proper solution. Here is my code. I have also tried creating a query through QSqlQuery and passing it into the QSQlQueryModel Object which did not work at all.
void MainWindow::on_login_clicked()
{
QSqlDatabase m_db;
QString path = "C:/Users/annea/Summer2019Database.db";
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName(path);
m_db.open();
if (!m_db.open())
{
qDebug() << "Error: connection with database fail";
}
else
{
qDebug() << "Database: connection ok";
}
QString username = ui->username->text();
QString password = ui->password->text();
QSqlQueryModel *queryModel = new QSqlQueryModel;
queryModel->setQuery("SELECT * FROM [User Database] WHERE Username= username"); //select the row of where the Username == username
queryModel->query().exec(); //execute it (not really sure why or what this does
if(queryModel->record(0).value(1).toString()== password) //if a row is found check column 2 for password
{
destroy(); //destroy current window
if(queryModel->record(0).value(3).toString()== 1) //if id is equal to one log in as user
{
user.showMaximized();
}
else {
dbManager.showMaximized();
}
}
else {
qWarning("Wrong Password or Username");
}
}
I think your query is wrong. Instead of writing like this:
queryModel->setQuery("SELECT * FROM [User Database] WHERE Username= username"); //select the row of where the Username == username
You might want writing like this:
queryModel->setQuery(QString("SELECT * FROM [User Database] WHERE Username = '%1'").arg(username)); //select the row of where the Username == username
Why? Because you are writing a query, and you probably want to check against the user name entered, not the string "username". Also, don't forget apostrophes when comparing.
In order to find more information which might help with your problem, you should read Qt's documentation regarding its' classes. Also, it would be beneficial to take a look into the SQLite WHERE clause and how strings are represented when writing queries:
https://doc.qt.io/qt-5/qsqlquerymodel.html#setQuery
https://doc.qt.io/qt-5/qsqlquery.html#QSqlQuery-1
http://www.sqlitetutorial.net/sqlite-where/
https://www.sqlite.org/datatype3.html

compare input to mysql database

item = test.query('SELECT userName FROM Database.Users WHERE userName = "user"', function (err,result){
if(err) throw err;
else if('user' == / something correct /){
console.log("TRUE");
}
console.log(result[0]);
});
What I want to do is to check if the user gives a valid username, like you would when logging in to a form of some sort. Now I might have taken the wrong approach but I've tried the following.
I tried to basically check if there is a user with username 'user', which exists in the mysql database. Then I want to simple check that the fixed input 'user' exists by comparing to the result that one gets from querying the DB. However it doesn't seem to work as the console never prints out "TRUE". However when I print out result[0] i get:
{ userName: 'user' }
Which is expected yet I can't manage to retrieve the string 'user'.
The query won't fail if there isn't a record with that username. It will only return an empty result set. Take out all the error stuff and check for number of records. You could also do a SELECT count(*) as recCnt where user = '$usr' and check the value of the returned recCnt variable.
You can try to use results[0].userName in your console.log

how to inject sql in login process

I've received an old application which completely lacks user input sanitization and is vulnerable to sql injection. To prove gravity of the situation i need to give client an example and what can be better to scare him than the login process. I've tried standard techniques but the problem with them is that they return multiple rows and due to nature of the code it returns an error instead of logging him in. What sql should i inject so that only a single row is returned and the execution reaches "return $access" line in order to pass the value of this "access" column to code calling this login function. The request is made via POST method and magic quotes are off on the server. Please let me know if you need any other information.
function login($username, $pw)
{
global $dbname, $connection, $sqluser, $sqlpw;
$db = mysql_connect($connection,$sqluser,$sqlpw);
mysql_select_db($dbname);
if(!($dba = mysql_query("select * from users where username = '$username' AND password = '$pw'"))){
printf("%s", sprintf("internal error5 %d:%s\n", mysql_errno(), mysql_error()));
exit();
}
$row = mysql_fetch_array($dba);
$access = $row['access'];
if ($access != ''){
return $access;
} else {
return "error occured";
}
mysql_close ($db);
}
Note: it turns out that magic_quotes_gpc is turned on and the php version is 5.2.17
Thanks
Starting with the goal query:
SELECT *
FROM users
WHERE username = '' OR '1'='1'
AND password = '' OR 1=1 LIMIT 1;#'
We get username is ' OR '1'='1 and password is ' OR 1=1 LIMIT 1;#
It depends what values the login function is called with. If there's sanitation before passing it to the function it might actually be safe. However it's better to filter it right before the query so you can see that your built query is safe.
However if you have something like this:
login($_POST['user'], $_POST['pass']);
In that case just put foo' OR 1=1 OR ' in the user field in the login form :)

Miscellaneous characters in MYSQL database?

$query = $db->prepare("SELECT id FROM users WHERE username = :username AND password = :password");
$query->bindValue(":username", $lName);
$query->bindValue(":password", imu($lPass));
var_dump(imu($lPass));
try {
$query->execute();
$result = $query->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die($e->getMessage());
}
I'm trying to select the users id, depending on if they entered a valid login. I tried to just use "WHERE username = :username" and that works, it returns the id, but when I add the password part, or only the password check, it returns null. I checked with var_dump as you can see and the password that it's dumping is correct, it exists in the database. The password is hashed with my own encryption system and it returns all kinds of characters. This specific password was: "®Ç+¥J:àhMaÕú¡HW".
I was wondering if there is anyway to get the id with the password check or do I have to edit my hash'er so it returns alphanumeric characters?
if there is anyway to get the id with the password check
yes.
do I have to edit my hash'er so it returns alphanumeric characters?
no.
The only issue with certain characters that can be is their encoding.
Make your password field either [var]binary() or make its collation utf8_bin