In mysql table name (user_login) and i having field like login_name and password . I entered in login_name as abc and password as /'(Special symbols like \ / ') .And my query is
select password from user_login where password like '/'' and
I got sql syntax error
You should use parameterised queries in what ever language you are implementing the call in. Beware SQL Injection attack
you should use parameters instead of putting varibles directly into the query. i think it's aproblem with the escaping symbol.
check out this link How to set query parameters in MySQL Query Browser?
If you ever use LIKE in a login system you have thrown ALL SECURITY OUT THE WINDOW. Try this on your login to see what I mean:
Username: %
Password: %
ACCESS GRANTED FOR FIRST USER IN DATABASE. ( pray that isn't an admin user )
If the username is known then % as a password will give full access.
If you want a friendlier system that is not case sensitive ( yes this reduces the possible number of passwords - but is likely appropriate for usernames ) then force the case to lower ( or upper or ucwords or whatever you prefer ) - but DO NOT use the LIKE operator in ANY QUERY involving a login or unscreened user input ( such as search boxes ). Anytime you must use the LIKE operator BE SURE TO STRIP OUT OR MANUALLY ESCAPE % and _ (and if you're using MS SQL then escape all the REGEX operators too - []^$()*. ).
A lot of escaping functions for mysql will not escape the % _ characters, which - when used with LIKE - allows any visitor the ability to do wildcard searches ( can severely bog down the server and cause DoS issues ) and worse grant themselves undue privileges using %:% to login.
Related
I am trying to verify user login my matching the input password to the password input by user
My insert query:
insert into login (Emp_id, Emp_Fname, Emp_Lname, Username, Password) values (5, 'TestFName', 'TestLName', 'Test', password('april'));
it stores the password as this value :
*72B46CDA233C759A88BEF81F59F66D78B26B2848
select * from login where password = '*72B46CDA233C759A88BEF81F59F66D78B26B2848'; -- this line shows me the result
select password('april'); -- this returns *72B46CDA233C759A88BEF81F59F66D78B26B2848
select * from login where password = 'password(april)'; -- this returns an empty set
Is there any alternative to this line of code?
I think you need to use:
select * from login where password = password('april');
So, don't quote the whole password function, just the argument to the function.
One cannot safely store passwords with pure SQL commands, instead a dedicated password-hash function of the development language should be used. In PHP this would be the functions password_hash() and password_verify() for the verification of the password.
Even more, MySql's password() function was never intended to be used with user passwords and is deprecated (will be removed in future versions). Have a look at the second note box in the documentation.
The reason why you cannot left the hashing to the SQL command is, that salted password hashes cannot be searched for in the database. The searching has to be done by user name only and afterwards one can verify the found password hash with the user input. A more in-depth explanation you can find in this answer.
https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_password says:
This function is deprecated as of MySQL 5.7.6 and will be removed in a future MySQL release.
PASSWORD() is used by the authentication system in MySQL Server; you should not use it in your own applications.
That wasn't an idle warning. https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password says:
This function was removed in MySQL 8.0.11.
So don't use PASSWORD() — unless you plan to never upgrade to MySQL 8.0.
Besides that, you have some problems in your code.
insert into login (Emp_id, Emp_Fname, Emp_Lname, Username, Password)
values (5, 'TestFName', 'TestLName', 'Test', password('april'));
I wouldn't use password (or any other hashing function) in this way, because you still have the plaintext password in your SQL statement. This ends up getting logged in query logs and statement-based binary logs, so it's a security weakness. That is, anyone who can get access to your logs can inspect the passwords.
Instead, hash the password in your app, and then put the result of that hash into your SQL statement.
Which hashing function you use depends on the language you use to write your application code. #martinstoeckli mentions a couple of functions that are used by PHP developers, but those won't be the same for other programming languages. You don't mention which language you use.
Likewise, when you search for a login that has that password, it works if you search for a specific hash string, but this doesn't work:
select * from login where password = 'password(april)'; -- this returns an empty set
The reason is that you're searching for the string 'password(april)'. Putting an expression in quotes means to use that literal string — it won't execute the function and use the result of it.
Again, you don't want to calculate the hash using SQL anyway. That puts the plaintext password into query logs and is not good for security.
You want to produce the hash string in your app, and then use the hash string in searches, like your first example. But not using the PASSWORD() function — using some application code function.
select * from login where password = '*72B46CDA233C759A88BEF81F59F66D78B26B2848';
(The hash string above is based on your example. It's a hash produced by MySQL's PASSWORD() function, only as strong as a SHA1 hash, which is known to be unsuitable for passwords.)
Actually, my preferred method is not to search for a password at all. Search for the login, and return the password hash string that is stored in the database.
select password from login where user = 'billkarwin'
Then in the application code, compare the hash string you fetched from the database against the re-calculation of the hash string based on the user's input when they're trying to log in.
(Massively edited because the responses were focusing on the wrong thing, which means I didn't formulate the question properly.)
I have a MySQL table with id, username and password fields. The password is encrypted. Part of the encryption uses the id of the record, specifically (in PHP):
md5 (md5('id') . $formPasswordCleaned)
To a validate a login form, I do the following (pseudo-code):
query database for the email address from login form
if num_rows > 0, $row = fetch_array
use $row['id'] to encrypt the password provided in the login form.
compare encrypted password with the one found in $row 4.
But, what I'd really like to do is one single SELECT command, that looks for a match on both email address and the encrypted password. But, since the password was encrypted using the row's id.....
Question: is it possible to write a SELECT statement that uses part of the forthcoming result as some of the arguments? Something like: SELECT * from users where email=$email and password=md5(md5($futureResult['id]).$password)
I realise it's self-referential, but I know just the basics of database usage and so I don't know what to search for (google or here) to find out if it's possible or how to do it, if it is indeed possible.
I want to authenticate users for a folder from a MySQL 5.1 database with AuthType Basic.
The passwords are stored in plain text (they are not really passwords, so doesn't matter).
The password format for apache however only allows for SHA1, MD5 on Linux systems as described here.
How could I generate the right format with an SQL query ? Seems like apache format is a binary format with a lenght of 20, but the mysql SHA1 function return 40 long.
My SQL query is something like this:
SELECT CONCAT('{SHA}', BASE64_ENCODE(SHA1(access_key))) FROM user_access_keys INNER JOIN users ON user_access_keys.user_id = users.id WHERE name = %s
where base64_encode is a stored function (Mysql 5.1 doesn't have TO_BASE64 yet). This query returns a 61 byte BLOB which is not the same format that apache uses. How could I generate the same format ?
You can suggest other method for this too. The point is that I want to authenticate users from a MySQL5.1 database using plain text as password.
The document you refer to does not mean to imply non-Linux by "Unix-only", therefore crypt() is available to you. Since you seem unconcerned about security I'd suggest this is the easiest option alongside MySQL's encrypt function. You may want to use a constant seed value in your queries.
SELECT ENCRYPT(access_key, 'SA') FROM user_access_keys INNER JOIN users ON user_access_keys.user_id = users.id WHERE name = %s
I've implemented my mail server as dictated here.
It works perfectly fine. My curiousity revolves around entering users into the database and authenticating them
Running:
INSERT INTO users (email, password) VALUES ('sales#example.com', ENCRYPT('password'));
Multiple times will give a different hash for the encrypted password as its utilizing a random salt. I.e. If I enter sales#example.com three times with the same password each hash is different...
My question to this is, how is it that the Postfix server can actually authenticate the password when a user logs in via a mail client?
There isn't any problem per say as it works fine, more just to satisfy my curiosity so I can fully understand whats going on behind the scenes to properly authenticate the encrypted password.
Postfix compares the password from the database to a new encrypt done with the salt(password from db).
to encrypt:
update user set password = ENCRYPT('1234') where id = 1
to check password:
SELECT u.* FROM user u where u.email ='admin#dominio.com'
and ENCRYPT('1234', u.password) = u.password
Read man crypt: it returns the salt in the first two chars of the return value.
So the salt is not lost, you can compare the encrypted string to the result of crypt( 'pass', $first_two_chars_of_encrypted_value ).
You must use ENCRYPT('pass','salt') to force a salt, otherwise the salt is lost forever and you have no way of recovering it. Fairly pointless function without it. It's a terrible function to use, though, because the security is so minimal; use PASSWORD() or OLD_PASSWORD() instead.
ENCRYPT() uses the system crypt(), which may use all or only the first 8 characters, must be printable 7-bit ascii, generally uses 1 round of a DES-based hash, and is completely unportable. Avoid it.
I've created a view of a table on a MySQL database to enable another application to use our existing (centralized) clients table.
Our passwords are stored as
md5(password + salt) + ":" + salt
Normally I decode this via a programming language of the given app we're connecting to it but...
This time it's a third party app and I only have SQL and one query to authorize a user.
Can you help me create a valid SQL query to authenticate?
The logic is straight forward:
Get salt for the given user, (everything after the colon)
combine the password and the salt
MD5 the password and salt
then compare the resulted md5 hash
the default sql query for this app is
select * from users
where userName=? and userPass=?
Thanks in advance.
I tried this and it works:
SELECT * FROM users
WHERE userPass = CONCAT(
MD5(CONCAT('xyzzy', (#salt := SUBSTRING_INDEX(userPass, ':', -1)))),
':', #salt)
AND userName = 'bkarwin';
I know you probably don't have the freedom to change anything, but FWIW, MD5() is not considered strong enough encryption for passwords. It's recommended to use SHA-256, which is available through the SHA2() function in MySQL 6.0.5.
select * from users where userName='MyUser' and userPass=concat(md5('MyPass'), ':', salt)
where salt=(
select substring(userPass FROM (instr(userPass, ':')+1)) from users
where userName='MyUser'
)