I know that I need to salt the hash, I’m just curious how a SQLInjection attack would be executed against this and I want to mitigate the risk
if (username && password) {
db.get(`SELECT * FROM users WHERE username = ? AND password = ?`, [username, hashString], (err, row) => {
if (err) {
console.error(err);
} else {
if (row) {
console.log('Login sucessful');
console.log('username input: ' + username + ' password input: ' + password + ' hash of password: ' + hashString);
console.log(row);
response.redirect('/index.html');
} else {
console.log('username input: ' + username + ' password input: ' + password + ' hash of password: ' + hashString);
console.log(row);
console.log('Invalid username or password');
response.redirect('/login.html');
response.end();
}
}
});
} else {
response.send('Please enter a username and password!');
response.end();
}
});
I tried adding some sql commands into the username and password slot. Nothing happens in the password box since it’s being hashed before it gets inserted into the sql command
2
Answers
The code appears to be using parameterized queries, which helps to prevent SQL injection attacks. However, one potential risk in the code is that the
hashString
parameter is not defined in the code snippet provided, so it is unclear how it is being generated. If it is being generated in an insecure way, it could potentially be manipulated by an attacker to execute a SQL injection attack.Example
A SQL injection attack could be attempted by entering a username and password combination that includes SQL code as part of the input. For example, an attacker could enter the following input as the password:
This input would cause the SQL query to evaluate as follows:
The double dash at the end of the input is a comment marker in SQL, which causes the remainder of the query to be ignored. The OR 1=1 condition is always true, which means that the query will return all rows from the users table, allowing the attacker to log in without a valid password.
Migrate this risk
To mitigate this risk, it is recommended to ensure that any input parameters used in the SQL query are properly sanitized and validated before being used. Additionally, it is recommended to use parameterized queries with prepared statements to prevent SQL injection attacks.
Update based on comment about
hashString
Using SHA-512 for hashing passwords does not directly increase the risk of an SQL injection attack.
However, using SHA-512 for password hashing is less secure compared to dedicated password hashing algorithms like
bcrypt
,scrypt
, orArgon2
. It does not provide sufficient protection against brute-force attacks and does not include a unique salt for each user, making it vulnerable to precomputed tables of hashed passwords (like rainbow tables).It’s not related to your original question but important to note, so here’s a quick example. I would recommend figuring out how you could implement it in your codebase if it’s important to you.
const bcrypt = require(‘bcrypt’);
const saltRounds = 10; // This value determines the "cost" of the hashing algorithm. A higher value means more computational power is required to hash and verify passwords, which is generally more secure. You can adjust this value based on your requirements.
Concept
The concept is simple it all boils down to the core SQL query.
these are the things to remember:
Now answer the question:
The above is the SQL query and the question mark is the endpoint for input.
and there is no sanitization in place.
So for the server to be manipulated we must comment out the check feature and the query must return true.
'--
: Will when injected in the username sectionThis will be the result:
The result will be like the password section will be commented and the check will be ignored.
Let’s change it a bit and set the payload to be:
'1=1--
Now, this will be the final query:
SELECT * FROM users WHERE username =''1=1 -- AND password =?
Now 1=1 is True that’s universal so the ” will return nothing and 1=1 will return True and the password section is ignored and the login is successful is bypassed.
Preventions
For prevention, there are 2 ways and both work well together they are:
When done on a normal application using a WAF won’t be appropriate but using sanitization is effective. the WAF operates by blocking such attacks once detected but sanitization strictly forbids certain inputs.
A basic sanitization code in Python:
The above code blocks characters such as
',-[]
etc cause these are a few of the most commonly used codes for injecting such attacks. Based on your usage you can manipulate it for using extra or not using extra characters but the more sanitized the better.