烧瓶中下载链接中的哈希整数

时间:2021-03-26 11:06:31

标签: python flask

我使用 Flask 开发了一个 Web 应用程序。 在渗透测试报告中,它说,如果下载功能有一个静态链接,那么下载链接应该是不可预测的。 所以我应该更改下载链接中的 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)

我怎么能做到这一点?

1 个答案:

答案 0 :(得分: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 的数据。但请注意,任何拥有令牌的人都可以读取此类数据,因为数据本身并未加密。