mirror of
https://github.com/simple-login/app.git
synced 2024-11-16 00:48:32 +01:00
Anti tamper: avoid submitting any suffix
This commit is contained in:
parent
5e174b08f4
commit
db92003e5f
4 changed files with 32 additions and 16 deletions
|
@ -123,6 +123,7 @@ DB_URI = os.environ["DB_URI"]
|
|||
# Flask secret
|
||||
FLASK_SECRET = os.environ["FLASK_SECRET"]
|
||||
MAILBOX_SECRET = FLASK_SECRET + "mailbox"
|
||||
CUSTOM_ALIAS_SECRET = FLASK_SECRET + "custom_alias"
|
||||
|
||||
# AWS
|
||||
AWS_REGION = "eu-west-3"
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<div class="col-sm-6 p-1">
|
||||
<select class="form-control" name="suffix">
|
||||
{% for suffix in suffixes %}
|
||||
<option value="{{ suffix[1] }}">
|
||||
<option value="{{ suffix[2] }}">
|
||||
{% if suffix[0] %}
|
||||
{{ suffix[1] }} (your domain)
|
||||
{% else %}
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
from flask import render_template, redirect, url_for, flash, request
|
||||
from flask_login import login_required, current_user
|
||||
from itsdangerous import TimestampSigner, SignatureExpired
|
||||
|
||||
from app.config import DISABLE_ALIAS_SUFFIX, ALIAS_DOMAINS
|
||||
from app.config import (
|
||||
DISABLE_ALIAS_SUFFIX,
|
||||
ALIAS_DOMAINS,
|
||||
CUSTOM_ALIAS_SECRET,
|
||||
)
|
||||
from app.dashboard.base import dashboard_bp
|
||||
from app.email_utils import email_belongs_to_alias_domains, get_email_domain_part
|
||||
from app.extensions import db
|
||||
|
@ -9,6 +14,8 @@ from app.log import LOG
|
|||
from app.models import Alias, CustomDomain, DeletedAlias, Mailbox
|
||||
from app.utils import convert_to_id, random_word, word_exist
|
||||
|
||||
signer = TimestampSigner(CUSTOM_ALIAS_SECRET)
|
||||
|
||||
|
||||
@dashboard_bp.route("/custom_alias", methods=["GET", "POST"])
|
||||
@login_required
|
||||
|
@ -24,27 +31,24 @@ def custom_alias():
|
|||
return redirect(url_for("dashboard.index"))
|
||||
|
||||
user_custom_domains = [cd.domain for cd in current_user.verified_custom_domains()]
|
||||
# List of (is_custom_domain, alias-suffix)
|
||||
# List of (is_custom_domain, alias-suffix, time-signed alias-suffix)
|
||||
suffixes = []
|
||||
|
||||
# put custom domain first
|
||||
for alias_domain in user_custom_domains:
|
||||
suffixes.append((True, "@" + alias_domain))
|
||||
suffix = "@" + alias_domain
|
||||
suffixes.append((True, suffix, signer.sign(suffix).decode()))
|
||||
|
||||
# then default domain
|
||||
for domain in ALIAS_DOMAINS:
|
||||
suffixes.append(
|
||||
(
|
||||
False,
|
||||
("" if DISABLE_ALIAS_SUFFIX else "." + random_word()) + "@" + domain,
|
||||
)
|
||||
)
|
||||
suffix = ("" if DISABLE_ALIAS_SUFFIX else "." + random_word()) + "@" + domain
|
||||
suffixes.append((False, suffix, signer.sign(suffix).decode()))
|
||||
|
||||
mailboxes = [mb.email for mb in current_user.mailboxes()]
|
||||
|
||||
if request.method == "POST":
|
||||
alias_prefix = request.form.get("prefix")
|
||||
alias_suffix = request.form.get("suffix")
|
||||
signed_suffix = request.form.get("suffix")
|
||||
mailbox_email = request.form.get("mailbox")
|
||||
alias_note = request.form.get("note")
|
||||
|
||||
|
@ -55,6 +59,18 @@ def custom_alias():
|
|||
flash("Something went wrong, please retry", "warning")
|
||||
return redirect(url_for("dashboard.custom_alias"))
|
||||
|
||||
# hypothesis: user will click on the button in the 300 secs
|
||||
try:
|
||||
alias_suffix = signer.unsign(signed_suffix, max_age=300).decode()
|
||||
except SignatureExpired:
|
||||
LOG.error("Alias creation time expired")
|
||||
flash("Alias creation time is expired, please retry", "warning")
|
||||
return redirect(url_for("dashboard.custom_alias"))
|
||||
except Exception:
|
||||
LOG.error("Alias suffix is tampered, user %s", current_user)
|
||||
flash("Unknown error, refresh the page", "error")
|
||||
return redirect(url_for("dashboard.custom_alias"))
|
||||
|
||||
if verify_prefix_suffix(
|
||||
current_user, alias_prefix, alias_suffix, user_custom_domains
|
||||
):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from flask import url_for
|
||||
|
||||
from app.config import EMAIL_DOMAIN
|
||||
from app.dashboard.views.custom_alias import signer
|
||||
from app.extensions import db
|
||||
from app.models import Mailbox
|
||||
from app.utils import random_word
|
||||
|
@ -12,14 +13,12 @@ def test_add_alias_success(flask_client):
|
|||
db.session.commit()
|
||||
|
||||
word = random_word()
|
||||
suffix = f".{word}@{EMAIL_DOMAIN}"
|
||||
suffix = signer.sign(suffix).decode()
|
||||
|
||||
r = flask_client.post(
|
||||
url_for("dashboard.custom_alias"),
|
||||
data={
|
||||
"prefix": "prefix",
|
||||
"suffix": f".{word}@{EMAIL_DOMAIN}",
|
||||
"mailbox": user.email,
|
||||
},
|
||||
data={"prefix": "prefix", "suffix": suffix, "mailbox": user.email,},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue