2015-08-28 39 views
-1

我在SQL中使用PASSWORD來哈希用戶密碼。構建SQL查詢時出現「不支持的操作數類型(%)」

sql = text('insert into account values("%s", "%s", "%s", PASSWORD("%s"), "1")'%(fname, lname, user_name, password)) 

當我嘗試使用密碼登錄時,它不允許我訪問該帳戶。

sql = text('select * from account where account.user_name = "%s" and account.password = PASSWORD("%s") and account.active = ' + '"' + '1' + '"')%(user_name, password) 

我得到的錯誤:

unsupported operand type(s) for %: 'TextClause' and 'tuple' 

我在做什麼錯試圖訪問加密的密碼是什麼時候?

+4

您很容易受到SQL注入攻擊。分別傳遞參數,而不是直接將它們格式化爲SQL字符串。 – davidism

回答

11

即時錯誤的是,在第一實施例時使用的字符串的字符串格式化%,然後在封閉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

+0

仍然存在登錄無法識別加密密碼的問題。 PASSWORD(%s)會在將其保存到數據庫時對其進行加密,但當我嘗試並檢索它時不會對其進行解密 – Ricky92d

+0

當您嘗試davidism的建議時,是否獲得了與%:'TextClause相同的「不受支持的操作數類型'和'元組'錯誤,還是不同的錯誤? –

+1

@ Ricky92d你在使用我的答案的第一部分還是第二部分?第二,你根本不應該使用「PASSWORD()」。我已經嘗試了兩種描述的解決方案,他們都爲我工作。 – davidism

相關問題