【问题标题】:Broken Access Control with JWT in Python在 Python 中使用 JWT 破坏访问控制
【发布时间】:2020-12-12 05:20:00
【问题描述】:

我目前正在开发一个使用 JWT 和 python 创建安全登录的项目。这是一个简单的银行账户应用程序,显示用户名、出生日期和账户余额。在我的代码中,我仍然可以通过更改分配给其他用户的 URL 帐号(例如 www.domain.com/account/#)来访问其他帐户。

如果 foo 是帐户 16 并且已登录,我可以将数字更改为 17,从而允许我访问 bar 的帐户,并提供他们的信息,这是一个很大的禁忌。我只想只能看到foo自己的账户信息。我正在尝试检查 JWT 以确保 foo 是用户,并且在将数据发送给用户之前它是 foo 的帐户信息。

传递给函数的 JWT 包含经过身份验证的用户的 usernamelogged_in 字段(或声明)。我正在尝试通过 URL 中的数字与正在数据库中查找的帐户进行比较。我还试图确保如果 JWT 中的用户名与从数据库返回的用户名不匹配,则引发“您无权访问”异常。

我一直在拼命想办法解决这个问题。

有效载荷

jwt_token = {
      "username": "foo",
      "logged_in": true
    }

代码

import jwt
import pymysql


class LoggedOutException(Exception):
    '''Raising a LoggedOutException will redirect the user to the login screen
    in the app.
    '''
    pass

def account_lookup(account_id, jwt_token):
    try:
        token = jwt.decode(jwt_token, 'secret', algorithm='HS256')
    except Exception as e:
        raise LoggedOutException('User is not logged in')

    if "logged_in" in token.keys() and token["logged_in"] == True:
        conn = pymysql.connect(
            host='mysql',
            port=3306,
            user='root',
            passwd='letmein',
            db='BankApp'
        )
        cursor = conn.cursor()

        statement = "SELECT username FROM tbl_user WHERE id = " + account_id + ";"
        cursor.execute(statement)
        username_results = cursor.fetchone()

        if username_results:
            username = username_results[0]

            statement = "SELECT balance, dob FROM tbl_account WHERE user_id = " + account_id + ";"
            cursor.execute(statement)
            account_results = cursor.fetchone()

            conn.commit()
            cursor.close()
            conn.close()

            return {
                'balance': account_results[0],
                'dob': account_results[1],
                'username': username
            }
        else:
            raise Exception('Account not found')
    else:
        raise LoggedOutException('User is not logged in')

【问题讨论】:

    标签: python jwt pymysql


    【解决方案1】:

    我也在尝试确保如果 JWT 中的用户名不 匹配从数据库返回的用户名,然后引发“你不 有访问权限”例外。

    在哪里?您的代码中没有这样的逻辑。您使用 JWT 仅根据 logged_in 值检查用户是否登录,这并没有多大帮助,因为只有登录的用户应该持有有效的 JWT 令牌,因此此类令牌本身的存在代表用户的登录状态。

    逻辑应该类似于当用户登录时,您为该用户生成一个 JWT 令牌,当该用户注销时,您使该令牌无效(当然,您可能还需要考虑实现令牌年龄和刷新稍后)。

    您的代码中有 2 个 SQL 查询

    statement = "SELECT username FROM tbl_user WHERE id = " + account_id + ";"
    statement = "SELECT balance, dob FROM tbl_account WHERE user_id = " + account_id + ";"
    

    但它们仅取决于 account_id 的值,它不是 JWT 的一部分(如果变量显然是 user_id,为什么还要使用 account_id 名称?这只是令人困惑)。

    简单的解决方案是将account_id(或更恰当地命名为user_id)放入JWT,而不是username(我认为),然后使用该值来获取数据来自数据库。

    【讨论】:

      猜你喜欢
      • 2021-10-23
      • 2021-03-22
      • 2017-03-09
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多