Fix: Add mising csrf validation for contact pgp key modification (#1463)
Co-authored-by: Adrià Casajús <adria.casajus@proton.ch>
This commit is contained in:
parent
327b672f24
commit
7e360bcbd9
|
@ -1,5 +1,7 @@
|
||||||
from flask import render_template, request, redirect, url_for, flash
|
from flask import render_template, request, redirect, url_for, flash
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import StringField, validators
|
||||||
|
|
||||||
from app.dashboard.base import dashboard_bp
|
from app.dashboard.base import dashboard_bp
|
||||||
from app.db import Session
|
from app.db import Session
|
||||||
|
@ -7,6 +9,14 @@ from app.models import Contact
|
||||||
from app.pgp_utils import PGPException, load_public_key_and_check
|
from app.pgp_utils import PGPException, load_public_key_and_check
|
||||||
|
|
||||||
|
|
||||||
|
class PGPContactForm(FlaskForm):
|
||||||
|
action = StringField(
|
||||||
|
"action",
|
||||||
|
validators=[validators.DataRequired(), validators.AnyOf(("save", "remove"))],
|
||||||
|
)
|
||||||
|
pgp = StringField("pgp", validators=[validators.Optional()])
|
||||||
|
|
||||||
|
|
||||||
@dashboard_bp.route("/contact/<int:contact_id>/", methods=["GET", "POST"])
|
@dashboard_bp.route("/contact/<int:contact_id>/", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def contact_detail_route(contact_id):
|
def contact_detail_route(contact_id):
|
||||||
|
@ -16,33 +26,41 @@ def contact_detail_route(contact_id):
|
||||||
return redirect(url_for("dashboard.index"))
|
return redirect(url_for("dashboard.index"))
|
||||||
|
|
||||||
alias = contact.alias
|
alias = contact.alias
|
||||||
|
pgp_form = PGPContactForm()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if request.form.get("form-name") == "pgp":
|
if request.form.get("form-name") == "pgp":
|
||||||
if request.form.get("action") == "save":
|
if not pgp_form.validate():
|
||||||
|
flash("Invalid request", "warning")
|
||||||
|
return redirect(request.url)
|
||||||
|
if pgp_form.action.data == "save":
|
||||||
if not current_user.is_premium():
|
if not current_user.is_premium():
|
||||||
flash("Only premium plan can add PGP Key", "warning")
|
flash("Only premium plan can add PGP Key", "warning")
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for("dashboard.contact_detail_route", contact_id=contact_id)
|
url_for("dashboard.contact_detail_route", contact_id=contact_id)
|
||||||
)
|
)
|
||||||
|
if not pgp_form.pgp.data:
|
||||||
contact.pgp_public_key = request.form.get("pgp")
|
flash("Invalid pgp key")
|
||||||
try:
|
|
||||||
contact.pgp_finger_print = load_public_key_and_check(
|
|
||||||
contact.pgp_public_key
|
|
||||||
)
|
|
||||||
except PGPException:
|
|
||||||
flash("Cannot add the public key, please verify it", "error")
|
|
||||||
else:
|
else:
|
||||||
Session.commit()
|
contact.pgp_public_key = pgp_form.pgp.data
|
||||||
flash(
|
try:
|
||||||
f"PGP public key for {contact.email} is saved successfully",
|
contact.pgp_finger_print = load_public_key_and_check(
|
||||||
"success",
|
contact.pgp_public_key
|
||||||
)
|
)
|
||||||
return redirect(
|
except PGPException:
|
||||||
url_for("dashboard.contact_detail_route", contact_id=contact_id)
|
flash("Cannot add the public key, please verify it", "error")
|
||||||
)
|
else:
|
||||||
elif request.form.get("action") == "remove":
|
Session.commit()
|
||||||
|
flash(
|
||||||
|
f"PGP public key for {contact.email} is saved successfully",
|
||||||
|
"success",
|
||||||
|
)
|
||||||
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"dashboard.contact_detail_route", contact_id=contact_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif pgp_form.action.data == "remove":
|
||||||
# Free user can decide to remove contact PGP key
|
# Free user can decide to remove contact PGP key
|
||||||
contact.pgp_public_key = None
|
contact.pgp_public_key = None
|
||||||
contact.pgp_finger_print = None
|
contact.pgp_finger_print = None
|
||||||
|
@ -53,5 +71,5 @@ def contact_detail_route(contact_id):
|
||||||
)
|
)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"dashboard/contact_detail.html", contact=contact, alias=alias
|
"dashboard/contact_detail.html", contact=contact, alias=alias, pgp_form=pgp_form
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
</h1>
|
</h1>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
{{ pgp_form.csrf_token }}
|
||||||
<input type="hidden" name="form-name" value="pgp">
|
<input type="hidden" name="form-name" value="pgp">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
|
|
Loading…
Reference in New Issue