Flask-MonitoringDashboard icon indicating copy to clipboard operation
Flask-MonitoringDashboard copied to clipboard

CSRF on Falsk monitoring dashboard not working

Open AmiyaSah14 opened this issue 2 years ago • 8 comments

Describe the bug A clear and concise description of what the bug is. I've imported flask_monitoringdashboard in my flask app as follows: import flask_monitoringdashboard as dashboard

and have used in the app as follows: dashboard.config.from_file('config.cfg') dashboard.bind(app) I've the respective config.cfg file too.

Flask Monitoring Dashboard is working fine if there is no CSRF implementation in the app. If I use CSRF in the app then it's working fine for the app, but while logging into the flask monitoring dashboard its throwing CSRF missing token exception.

So how to implement CSRF for the Flask Monitoring Dashboard ?

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior A clear and concise description of what you expected to happen.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. MacOS 10.14.3]
  • Browser [e.g. chrome, safari]
  • FMD Version [e.g. 2.1.4]

Additional context Add any other context about the problem here.

AmiyaSah14 avatar Jan 23 '22 08:01 AmiyaSah14

What I did was to edit fmd_login.html in flask_monitorindashboard.html under venv/lib/python3.8/site-packages/flask_monitoringdashboard/templates/ and added a hidden input to the form.

aenescu avatar Mar 16 '22 10:03 aenescu

thanks for the answer @aenescu!

do you have a snippet of the solution? maybe we should try to add it in the actual FMD implementation so you don't have to modify anything.

mircealungu avatar Mar 16 '22 11:03 mircealungu

First line after <form class="form" method="POST" action="login">. It would be helpful to have it in the actual implementation

{% extends "fmd_base.html" %} {% block body %}

<body>
  <div class="container py-5">
    {% if show_login_banner %}
    <div class="row">
      <div class="col-md-8 offset-md-2">
        <div class="text-center" style="margin-bottom: 20px; margin-top: -30px">
          <div style="text-align: center">
            <img
              src="{{ url_for(blueprint_name + '.static', filename='img/header.png') }}"
              width="80%"
            />
          </div>
          <span
            >Automatically monitor the evolving performance of Flask/Python web
            services</span
          >
        </div>
      </div>
    </div>
    {% endif %}

    <div class="row">
      <div class="col-md-4 offset-md-4">
        <span class="anchor" id="formLogin"></span>
        <div class="card card-outline-secondary">
          <div class="card-header">
            <h5>Login</h5>
          </div>

          <div class="card-body">
            <form class="form" method="POST" action="login">
                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
                <div class="form-group">
                <label for="formName"><i class="fa fa-user"></i> Login</label>
                <input
                  id="formName"
                  name="name"
                  type="text"
                  class="form-control"
                  placeholder="Username"
                  autofocus
                  required
                />
              </div>

              <div class="form-group">
                <label for="formPassword"
                  ><i class="fa fa-lock"></i> Password</label
                >
                <input
                  name="password"
                  type="password"
                  class="form-control"
                  placeholder="Password"
                  required
                />
              </div>

              <button name="Login" class="btn btn-primary btn-block">
                Login
              </button>
            </form>
            <hr />
            {% if show_login_footer %}
            <div class="text-center">
              For advanced documentation, see
              <a
                target="_blank"
                href="http://flask-monitoringdashboard.readthedocs.io"
                >this site</a
              >
            </div>
            {% endif %}
          </div>
        </div>
      </div>
    </div>
  </div>
</body>

aenescu avatar Mar 16 '22 12:03 aenescu

Nice @aenescu! Do you want to send a PR with your fix? In that case your contribution would also be captured in the history of FMD ;)

mircealungu avatar Mar 16 '22 14:03 mircealungu

@aenescu - just a friendly reminder about the previous question :)

mircealungu avatar Mar 23 '22 18:03 mircealungu

Hi Mircea,

Sorry for the late reply. I will make a PR tomorrow. Thank your for your suggestion :)

On Wed, Mar 23, 2022, 20:11 Mircea Filip Lungu @.***> wrote:

@aenescu https://github.com/aenescu - just a friendly reminder about the previous question :)

— Reply to this email directly, view it on GitHub https://github.com/flask-dashboard/Flask-MonitoringDashboard/issues/411#issuecomment-1076660577, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIC6C2TDR54OVPD5D5QEQGDVBNNDPANCNFSM5MTCNEIA . You are receiving this because you were mentioned.Message ID: @.*** com>

aenescu avatar Mar 23 '22 18:03 aenescu

Hi @AmiyaSah14 , thank you for bringing up this issue and taking the time to contribute to the Flask-MonitoringDashboard project.

As part of my school project, my team is conducting a usability research study to improve the dashboard. I noticed your experience with the app and thought it would be valuable to gather more insights from you.

Would you be open to receiving a few questions about your experience with Flask-MonitoringDashboard? It won't take more than 20 minutes to answer them. Your feedback will play a vital role in enhancing the app's functionality and addressing any existing limitations.

If you're interested, please let me know, and I will send you the questions. Your involvement would be highly valuable and greatly appreciated.

HrisyToteva avatar Jul 14 '23 08:07 HrisyToteva

First line after <form class="form" method="POST" action="login">. It would be helpful to have it in the actual implementation

{% extends "fmd_base.html" %} {% block body %}

<body>
  <div class="container py-5">
    {% if show_login_banner %}
    <div class="row">
      <div class="col-md-8 offset-md-2">
        <div class="text-center" style="margin-bottom: 20px; margin-top: -30px">
          <div style="text-align: center">
            <img
              src="{{ url_for(blueprint_name + '.static', filename='img/header.png') }}"
              width="80%"
            />
          </div>
          <span
            >Automatically monitor the evolving performance of Flask/Python web
            services</span
          >
        </div>
      </div>
    </div>
    {% endif %}

    <div class="row">
      <div class="col-md-4 offset-md-4">
        <span class="anchor" id="formLogin"></span>
        <div class="card card-outline-secondary">
          <div class="card-header">
            <h5>Login</h5>
          </div>

          <div class="card-body">
            <form class="form" method="POST" action="login">
                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
                <div class="form-group">
                <label for="formName"><i class="fa fa-user"></i> Login</label>
                <input
                  id="formName"
                  name="name"
                  type="text"
                  class="form-control"
                  placeholder="Username"
                  autofocus
                  required
                />
              </div>

              <div class="form-group">
                <label for="formPassword"
                  ><i class="fa fa-lock"></i> Password</label
                >
                <input
                  name="password"
                  type="password"
                  class="form-control"
                  placeholder="Password"
                  required
                />
              </div>

              <button name="Login" class="btn btn-primary btn-block">
                Login
              </button>
            </form>
            <hr />
            {% if show_login_footer %}
            <div class="text-center">
              For advanced documentation, see
              <a
                target="_blank"
                href="http://flask-monitoringdashboard.readthedocs.io"
                >this site</a
              >
            </div>
            {% endif %}
          </div>
        </div>
      </div>
    </div>
  </div>
</body>

with this solution, the problem is still there because more routes in this module use the POST method, and all of them will raise errors without CSRF tokens including the API routes. so it could not be a good solution. you just solved the problem for the login page but the problem is still there in other routes

A better solution is introducing the MonitoringDashboard blueprint as an exception in the CSRFProtect:

csrf.exempt(dashboard.blueprint)

amirhnir avatar Nov 25 '23 14:11 amirhnir