SQL-based authentication: Difference between revisions

→‎{{header|Python}}: Fixed SQL injection; changed library to the official one; fixed some other issues
m (format SQL as SQL)
(→‎{{header|Python}}: Fixed SQL injection; changed library to the official one; fixed some other issues)
Line 452:
 
=={{header|Python}}==
{{works with|Python|2.7}}
{{improve|Python|This example is missing proper encoding or bound parameters to avoid SQL injection, which are present in the other examples. In general is is an unsafe practice to create sql commands directly with string operations}}
Uses the [http://dev.mysql.com/downloads/connector/python/ official Python MySQL connector]
<lang python>'''with Python 2.6, gives a deprecation warning for sets module, but works'''
<lang python>import MySQLdbmysql.connector
import hashlib
import sys
import random
DB_HOST = "localhost"
DB_USER = "devel"
DB_PASS = "devel"
DB_NAME = "test"
def connect_db():
''' Try to connect DB and return DB instance, if not, return False '''
try:
return MySQLdbmysql.connector.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME)
except:
return False
def create_user(username, passwd):
''' if user was successfully created, returns its ID; returns None on error '''
db = connect_db()
if not db:
print '"Can\'t connect MySQL!' "
sys.exit(1) return None
cursor = db.cursor()
 
salt = randomValue(16)
passwd_md5 = hashlib.md5(salt+passwd).hexdigest()
# If username already taken, inform it
try:
cursor.execute("INSERT INTO users (`username`, `pass_salt`, `pass_md5`) VALUES ('%s', '%s', '%s')" %, (username, salt, passwd_md5))
cursor.execute("SELECT userid FROM users WHERE username='%s'", %(username,) username)
id = cursor.fetchallfetchone()
return id[0][0] db.commit()
salt = cursor.fetchoneclose()[0]
db.close()
return Trueid[0]
except:
print 'Username was already taken. Please select another'
sys.exit(1) return None
def authenticate_user(username, passwd):
db = connect_db()
if not db:
print '"Can\'t connect MySQL!' "
sys.exit(1) return False
cursor = db.cursor()
scheck = cursor.execute("SELECT pass_salt, pass_md5 FROM users WHERE username='%s'" %, (username,))
 
row = cursor.fetchone()
try:
cursor.close()
scheck = cursor.execute("SELECT pass_salt FROM users WHERE username='%s'" % (username))
except:db.close()
if row is None: # username not found
return False
salt = row[0]
 
ifcorrect_md5 scheck == 0:row[1]
passwdtried_md5 = hashlib.md5(salt+passwd).hexdigest()
return False
return correct_md5 == tried_md5
 
salt = cursor.fetchone()[0]
passwd = hashlib.md5(salt+passwd).hexdigest()
# cursor returns 1 if query is successfull else it returns 0
user = cursor.execute("SELECT userid, username FROM users WHERE username='%s' AND pass_md5='%s'" % (username, passwd))
if user != 0:
return True
else:
return False
def randomValue(length):
''' Creates random value with given length'''
salt_chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
 
output = ""
return ''.join(random.choice(salt_chars) for x in range(length))
for x in range(length):
rand = random.randrange(0, 35)
output = output + salt_chars[rand]
return output
if __name__ == '__main__':
user = randomValue(10)
passwd = randomValue(16)
 
new_user_id = create_user(user, passwd)
if new_user_id is None:
print 'Failed to create user %s' % user
sys.exit(1)
auth = authenticate_user(user, passwd)
if auth:
print 'User %s authenticated successfully' % user
else:
print 'User %s failed' % user</lang>
</lang>
 
=={{header|Raven}}==
Anonymous user