【问题标题】:hash int in download link in flask烧瓶中下载链接中的哈希整数
【发布时间】:2021-06-23 05:01:43
【问题描述】:

我使用flask 开发了一个网络应用程序。 在渗透测试报告中,它说,如果下载功能有一个静态链接,那么下载链接应该是不可预测的。 所以我应该改变下载链接中的int。

html:

                            <td><a href="{{ url_for('course_chat_export_csv', group_id=g.id) }}"
                               target="_blank">CSV</a> |
                            <a href="{{ url_for('course_chat_export_excel', group_id=g.id) }}"
                               target="_blank">Excel</a></td>

routes.py:

@app.route('/course/download/<int:group_id>/csv', methods=['GET', 'POST'])
  def export_csv(group_id):
    group = Group.query.get(group_id)
    file_name = str.lower(group.title) + ".csv"
    messages = Message.query.filter(Message.to_id == group.chat_id).order_by(Message.date.asc()).all()
    temp = os.path.join(app.root_path, 'temp')
    export_csv(messages, os.path.join(temp, file_name))
    return  send_from_directory(directory=temp, file_name=file_name, as_attachment=True,
                                     attachment_filename=file_name)

我怎样才能做到这一点?

【问题讨论】:

    标签: python flask


    【解决方案1】:

    您可以使用JWT换取下载链接。

    @app.route('/course/download/<str:token>/csv', methods=['GET', 'POST'])
    def export_csv(token):
        try:
            data = jwt.decode(token, current_app.secret_key, algorithms=["HS256"])
        except jwt.exceptions.InvalidTokenError:
            return "invalid token", 401
    
        group_id = data["group_id"]
        group = Group.query.get(group_id)
        file_name = str.lower(group.title) + ".csv"
        messages = Message.query.filter(Message.to_id == group.chat_id).order_by(Message.date.asc()).all()
        temp = os.path.join(app.root_path, 'temp')
        export_csv(messages, os.path.join(temp, file_name))
        return  send_from_directory(directory=temp, file_name=file_name, as_attachment=True,
                                         attachment_filename=file_name)
    

    您可以使用 jwt 模块生成此类令牌。

    import jwt
    from datetime import datetime, timedelta
    JWT_EXP_DELTA_SECONDS = 20000
    
    group_id = 25
    token = jwt.encode(
                {"group_id": group_id , "exp": datetime.utcnow() + timedelta(seconds=JWT_EXP_DELTA_SECONDS)},  # exp is optional, but you can use it if you want the download link only to work during a certain period of time
                current_app.config["INVITES_SECRET"],
                algorithm="HS256",
            )
    

    在 jwt 的数据部分中,您还可以包含 userId,然后检查当前登录的用户是否对应于它用于下载的 url。 (如果您有身份验证)

    另一种需要使用数据库的方法是,只需将令牌更改为随机长字符串,然后在数据库中存储随机字符串和组 ID 之间的关系。

    当然,任何类型的加密字符串都可以;但是使用 JWT 为您提供了一个完善的协议,您可以使用它来传递 group_id 甚至 user_id 的数据。但请注意,任何拥有令牌的人都可以读取此类数据,因为数据本身并未加密。

    【讨论】:

    • 你使用哪个版本的 jwt?有些版本没有encode方法
    • 版本是什么意思?你有什么链接到你提到的吗?还是你的意思是算法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2012-05-06
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    相关资源
    最近更新 更多