的即時錯誤的是,在第一實施例時使用的字符串的字符串格式化%
,然後在封閉text
的結果,而第二個嘗試使用字符串text
對象格式化。
更嚴重的問題是,你已經打開自己注入攻擊通過直接格式化用戶輸入到SQL字符串,而不是單獨傳遞它們。
它看起來像你正在使用Flask-SQLAlchemy。在這種情況下,寫一個參數化查詢並將參數傳遞給execute
。
db.engine.execute(
'insert into account values(?, ?, ?, PASSWORD(?), ?)',
(fname, lname, user_name, password, True)
)
db.engine.execute(
'select * from account where account.user_name = ? and account.password = PASSWORD(?) and account.active = ?,
(user_name, password, True)
)
參數化的概念與任何其他數據庫驅動程序類似。
而不是依賴數據庫來散列的口令,使用passlib
庫是一個更強大的替代方案。它包含更強大的哈希,以及「貶低」哈希和升級存儲值的能力。
from passlib.hash import pbkdf2_sha512
# when creating a user, generate the hash with passlib
# and don't use PASSWORD() in SQL
password = pbkdf2_sha512.encrypt('secret')
# example login
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
r = engine.execute('select * from account where account.name = ? and account.active = ?', (username, True))
if r:
user = r[0]
# verify the hash using passlib, not SQL
if pbkdf2_sha512.verify(password, user.password):
# active user, correct password, do the login
return 'good credentials'
# incorrect username or password
return 'bad credentials'
return render_template('login.html')
在通過這些哈希值,而不是調用SQL PASSWORD
。
您很容易受到SQL注入攻擊。分別傳遞參數,而不是直接將它們格式化爲SQL字符串。 – davidism