sqlite 寻求帮助以了解和修复Flask应用程序中的SQL注入漏洞

vsaztqbk  于 2023-05-23  发布在  SQLite
关注(0)|答案(2)|浏览(284)

我为一个项目开发了一个Flask应用程序,最近一个朋友指出它可能容易受到SQL注入攻击。我需要帮助来理解和解决这个漏洞。
我的应用程序与sqlite3数据库交互以检索和存储用户数据。它利用SQL查询来执行数据库操作。但是,我不确定SQL注入攻击是如何工作的,以及如何防止它们。
有没有人能解释一下SQL注入的概念,并提供有关保护我的Flask应用程序免受此漏洞影响的指导?此外,如果您能检查我的代码并建议任何必要的更改以防止SQL注入,我将不胜感激。

from flask import Flask, request, jsonify, render_template
import hashlib
import sqlite3
import jwt

app = Flask(__name__)

secret = "$up3r_$3cur4_t0k3n"

def check_username(username):
        conn = sqlite3.connect('users.db')
        cur = conn.cursor()
        cur.execute(f"SELECT * FROM users WHERE username='{username}'")
        res = cur.fetchone()
        if res:
                return True

@app.route('/')
def home():
        return render_template('index.html')

@app.route('/api/v3/signup', methods=['POST'])
def signup():
        username = request.json.get('uname')
        password = request.json.get('pwd')
        if check_username(username):
                return jsonify({"message":"User already exists"}), 200
        conn = sqlite3.connect('users.db')
        cur = conn.cursor()
        cur.execute(f"INSERT INTO users (username, password, isAdmin) VALUES ('{username}', '{hashlib.sha256(password.encode()).hexdigest()}', 0)")
        conn.commit()
        conn.close()
        return jsonify({"message":"User Created Successfully."}), 200

@app.route('/api/v3/login', methods=['POST'])
def login():
        username = request.json.get('uname')
        password = request.json.get('pwd')
        conn = sqlite3.connect('users.db')
        cur = conn.cursor()
        cur.execute(f"SELECT * FROM users WHERE username='{username}' AND password='{hashlib.sha256(password.encode()).hexdigest()}'")
        res = cur.fetchone()
        if not res:
                return jsonify({"message":"Wrong Username/Password"}), 401
        data = {"username":res[0], "isAdmin":res[2]}
        jwt_data = jwt.encode(payload=data, key=secret)
        return jsonify({"auth":jwt_data.decode()}), 200

@app.route('/api/v3/validate', methods=['POST'])
def validate():
        auth = request.json.get('auth')
        data = jwt.decode(auth, key=secret, algorithms=['HS256', ])
        if data["username"] == 'admin' and data['isAdmin'] == True:
                return jsonify({"message":f"Welcome admin! Hope you're okay."})
        else:
                return jsonify({"message":f"Welcome {data['username']}!"})

if __name__ == '__main__':
        app.run('0.0.0.0',8090, debug=True)

我试着在谷歌上搜索这个问题,但一切都超出了我的头脑。

sqougxex

sqougxex1#

所以我检查了你的代码,发现有3行需要修改以防止SQL注入。
第13行:

cur.execute(f"SELECT * FROM users WHERE username='{username}'")

改成

cur.execute(f"SELECT * FROM users WHERE username=?",(username,))

第三十行:

cur.execute(f"INSERT INTO users (username, password, isAdmin) VALUES ('{username}', '{hashlib.sha256(password.encode()).hexdigest()}', 0)")

改成

cur.execute(f"INSERT INTO users (username, password, isAdmin) VALUES (?, '{hashlib.sha256(password.encode()).hexdigest()}', 0)",(username,))


第四十一行:

cur.execute(f"SELECT * FROM users WHERE username='{username}' AND password='{hashlib.sha256(password.encode()).hexdigest()}'")

改成

cur.execute(f"SELECT * FROM users WHERE username=? AND password='{hashlib.sha256(password.encode()).hexdigest()}'",(username,))
nafvub8i

nafvub8i2#

让我们假设你有这个SQL语句:

"SELECT * FROM users WHERE username='{username}'"

{username}是用户传入的值(从他们正在填写的表单,他们正在调用的API等)。
如果传入的值为
'dsolanki'' AND active_flg = ''Y'' '
然后执行的SQL语句是:

"SELECT * FROM users WHERE username='dsolanki' AND active_flg = 'Y'"

也就是说,一个不同于你在代码中写的SQL语句。显然这是一个简单的例子,不会造成任何损害(即使它没有错误地执行)--除了可能不返回一个确实存在的记录。但是,如果您的代码/语言在一个字符串中接受多个SQL语句,则可以传递如下输入
'dsolanki''; DELETE * FROM users;'
这将在代码中生成以下SQL语句:

SELECT * FROM users WHERE username='dsolanki'; 
DELETE * FROM users;

这显然会造成损害。
因此,验证输入字符串的内容以确保它们符合适当的规则(例如:用户名不能包含空格,长度必须为8个字符,等等)-以确保SQL注入攻击失败
希望这能帮上忙?

相关问题