Reject all collations other than latin1_swedish_ci - python

I have a log-in system, and when I enter a special symbol such as ○ I get this error message...
mysql.connector.errors.DatabaseError: 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation '='
I think the best way to deal with this is when asking for the users username, reject inputs that are not in latin1_swedish_ci, e.g. alt codes like ☺. How would I do this? Relevant code:
username = input("Enter username")
password = input("Enter password")
insertData = "INSERT INTO users(username, password) VALUES (%s, %s)"
cursor.execute(insertData, [(username), (password)]) #Execute SQL statement
db.commit() #Commit changes

Is this problem coming from an HTML <form> that you control? If so, it probably has (or the browser defaults to)
<form accept-charset="UTF-8">.
Change that to accept only whatever the equivalent of latin1 is. That is, add the following to your form tag:
accept-charset="ISO-8859-1"

Related

Tried using Python flask to make data sent from HTML <form> a tuple to match selected data from a MySQL table if exit, but something went wrong

// 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.

How can I loop through form’s in flask/python?

I have one page HTML with few submit buttons with different names and values. I have all the names of the buttons in one db in SQL. When the user enter in the page usually he click just in one button each time and the form is submitted. How can I loop through this buttons in my flask/python program?
connection = sqlite3.connect('world.db')
cursor = connection.cursor()
sqlite_select_query = """SELECT name FROM countries"""
cursor.execute(sqlite_select_query)
records = cursor.fetchall()
for row in records:
wish = request.form[row[0]]
try:
db.execute("INSERT INTO userinput (user_id, wish, country_name) VALUES (?, ?, ?)", user_id, wish, row[0])
except ValueError:
db.execute("UPDATE userinput SET wish = ? WHERE user_id =? AND country_name=?", wish, user_id, row[0] )
except:
pass
I have one error 400 Bad request.
Ps.: I already tried to put the value of row between ' and ". Doesn't changed anything.
If I put my request.form inside the try session, it just pass.
I put before few "prints" to see where is the error and see that is in the request form.
If I put the name direct in request form and outside the loop for example ‘’’ request.form[“Brazil”]’’’ I can insert in the database with no problems.
Thanks.
I am pretty sure request.form does not contain all countries, just the one associatted button is clicked. You could look at server logs, probably you see info about missing key in request.form. So what you want to is find that specific one:
wish = request.form.get(row[0])
if wish is None:
continue

Retrieve a value from MongoDB and set a string to it in Python(Pymongo)

I am trying to retrieve a value from MongoDB and set a string to it in Python with MongoDB. Here is my user registration function:
def registerAccount():
registerUsername = input('Please input a username to be registered into our database.')
registerPassword = input('Please input a password to be entered into our database.')
passwordHash = sha256_crypt.hash(registerPassword)
regDetails = {
"username": registerUsername,
"passwordhash": passwordHash
}
db = client.pinnacle
users = db.users
users.insert(regDetails)
and here is my login function:
def login():
db = client.pinnacle
users = db.users
pwHash = users.find_one({"passwordhash"})
print(str(pwHash))
loginUsername = input('Please input username to be signed in.')
loginPassword = input('Please input password to be signed in.')
# pprint.pprint(users.find_one({"username": "1"}))
# example = users.find_one({"username": "1"})
pbkdf2_sha256.verify(loginPassword, pwHash)
Basically, I need to search the database for the username, and get the string right after the username which is passwordHash. Then I will set pwHash to that string which will be checked with PassLib. Help is appreciated. Thanks!
Also if anyone is interested you can see my full code here.
this happens whenever i select to login, even after not typing in username or password
The error is caused by this line below:
pwHash = users.find_one({"passwordhash"})
Where you should specify a filter of key/value pair, instead it's only specifying a key. You should remove the line above (and the print line right after it). See also pymongo find_one() method for more info.
Also, in the same function login(), you have a typo for key username.
user = users.find_one({"userName": loginUsername})
Note that it should be lowercase username to be consistent with how you're storing them elsewhere in the code.
Lastly, you should replace
pbkdf2_sha256.verify(loginPassword, user['passwordhash'])
with below method, as this is how you encrypt it in the registerAccount()
sha256_crypt.verify(loginPassword, user['passwordhash'])
Please consider adding error checks throughout your code. i.e. if users.find_one() returns None do XYZ.

SQL Injection Vulnerability Identification in Python [duplicate]

This question already has answers here:
Python SQLite3 SQL Injection Vulnerable Code
(3 answers)
Closed 7 years ago.
I am supposed to look at this chunk of code and decide what parts could be vulnerable to SQL Injection, why and add fixes to them. I have been scanning the code looking for places that have too vague of parameters and such but i am having trouble finding places that could possibly be vulnerable. If anyone can just quickly scan through this code and point out any blatant vulnerabilities that would be great. The program really likes to give error messages when input is given with single quotes. This code is part of a program that tracks activities. There are 3 input fields, username, password and name of activity. Can post more code if anyone wants
#!/usr/bin/python3.4
import readline
import sqlite3
def audit(handle, event, obj=None):
"""Log an audit event."""
if handle[2] is None:
handle[2]=-1;
if obj==None:
handle[0].execute("insert into auditlog(userid, event)"
" values({0}, '{1}')".format(handle[2],event))
else:
handle[0].execute("insert into auditlog(userid, event, object)"
" values({0}, '{1}', {2})".format(str(handle[2]),
event, obj))
if handle[0].lastrowid is None:
"""On error, raise a SystemException"""
handle[1].commit()
handle[1].close()
raise SystemError("Error creating audit log entry.",
handle[2],event,obj)
handle[1].commit()
def register(cursor, connection, username, password):
"""Register a new user and return a connection to the database."""
cursor.execute("insert into user(username, password)"
" values('{0}', '{1}')".format(username, password))
userid=cursor.lastrowid;
if userid>0:
audit((cursor, connection, userid), "registered")
connection.commit()
print("Welcome, new user!")
return (cursor, connection, userid)
"""If the user could not be registered, raise a SystemError."""
audit((cursor, connection, 0),
"registeration error for {0}".format(username))
connection.commit()
connection.close()
raise SystemError("Unknown error registering user",username)
def connect(username, password):
"""Attempt to log in as the specified user."""
connection=sqlite3.connect('timelog.db')
cursor=connection.cursor()
"""The database is created if necessary."""
cursor.execute("create table if not exists user"
"( id integer primary key,"
" username varchar(50) unique not null,"
" password char(40) not null,"
" created datetime default CURRENT_TIMESTAMP,"
" modified datetime default CURRENT_TIMESTAMP"
")")
For example this statement is vulnerable to SQL injection:
cursor.execute("insert into user(username, password)"
" values('{0}', '{1}')".format(username, password))
I could for example enter the username:
test','secret');update user set password='';--
You should use parametrised queries instead. Using SQLLite you can call the sql like this instead:
cmd = "insert into user(username, password values(?, ?)"
curs.execute(cmd, (username, password))

How can I prevent insertion conflict when inserting a variable to a sqlite table?

Hey I'm okay with writing to the table, except unable to check of the data is already there and if the data is then don't write the data and print a value saying that it already exists.
Here is what I have so far
def createAccount():
username = raw_input("username: ")
password = raw_input("password: ")
c.execute("INSERT INTO Logindetails(Username, Password) VALUES (?,?)",
(username, password,))
conn.commit()
Thanks if you can help me, its for my coursework and I'm pretty new to all this.
If you change the create table statement to the following, sqlite will know that each username must be unique because you're defining a 'PRIMARY KEY', one that must be unique:
c.execute("""CREATE TABLE LoginDetails
(Username text PRIMARY KEY, Password text)""")
If you then attempt to insert a row into the table with an existing username, an integrity error will occur:
IntegrityError: column username is not unique
You can catch this (and other errors similarly) using a try, except clause as follows (this assumes you're using sqlite3):
try:
c.execute("INSERT INTO Logindetails(Username, Password) VALUES (?,?)",(username, password,))
except sqlite3.IntegrityError:
print("Username already exists!")

Categories

Resources