implement anti-csrf measures in all posted forms

This commit is contained in:
forest 2020-05-22 16:04:47 -05:00
parent 2b0ff06ec8
commit fd7dd7390f
5 changed files with 35 additions and 6 deletions

View File

@ -1,6 +1,8 @@
import functools import functools
import re import re
from nanoid import generate
from flask import Blueprint from flask import Blueprint
from flask import flash from flask import flash
from flask import current_app from flask import current_app
@ -22,7 +24,7 @@ def account_required(view):
@functools.wraps(view) @functools.wraps(view)
def wrapped_view(**kwargs): def wrapped_view(**kwargs):
if session.get("account") is None: if session.get("account") is None or session.get("csrf-token") is None :
return redirect(url_for("auth.login")) return redirect(url_for("auth.login"))
return view(**kwargs) return view(**kwargs)
@ -69,6 +71,8 @@ def magiclink(token):
if email is not None: if email is not None:
session.clear() session.clear()
session["account"] = email session["account"] = email
session["csrf-token"] = generate()
return redirect(url_for("console.index")) return redirect(url_for("console.index"))
else: else:
# this is here to prevent xss # this is here to prevent xss

View File

@ -85,9 +85,17 @@ def detail(id):
return render_template("capsul-detail.html", vm=vm, delete=True, deleted=True) return render_template("capsul-detail.html", vm=vm, delete=True, deleted=True)
if request.method == "POST": if request.method == "POST":
if 'are_you_sure' not in request.form or not request.form['are_you_sure']: if "csrf-token" not in request.form or request.form['csrf-token'] != session['csrf-token']:
return abort(418, f"u want tea")
return render_template("capsul-detail.html", vm=vm, delete=True, deleted=False) if 'are_you_sure' not in request.form or not request.form['are_you_sure']:
return render_template(
"capsul-detail.html",
csrf_token = session["csrf-token"],
vm=vm,
delete=True,
deleted=False
)
else: else:
current_app.logger.info(f"deleting {vm['id']} per user request ({session['account']})") current_app.logger.info(f"deleting {vm['id']} per user request ({session['account']})")
current_app.config["VIRTUALIZATION_MODEL"].destroy(email=session['account'], id=id) current_app.config["VIRTUALIZATION_MODEL"].destroy(email=session['account'], id=id)
@ -102,7 +110,9 @@ def detail(id):
return render_template( return render_template(
"capsul-detail.html", "capsul-detail.html",
vm=vm, delete=False, csrf_token = session["csrf-token"],
vm=vm,
delete=False,
durations=list(map(lambda x: x.strip("_"), metric_durations.keys())), durations=list(map(lambda x: x.strip("_"), metric_durations.keys())),
duration=duration duration=duration
) )
@ -119,6 +129,8 @@ def create():
errors = list() errors = list()
if request.method == "POST": if request.method == "POST":
if "csrf-token" not in request.form or request.form['csrf-token'] != session['csrf-token']:
return abort(418, f"u want tea")
size = request.form["size"] size = request.form["size"]
os = request.form["os"] os = request.form["os"]
@ -193,6 +205,7 @@ def create():
return render_template( return render_template(
"create-capsul.html", "create-capsul.html",
csrf_token = session["csrf-token"],
capacity_avaliable=capacity_avaliable, capacity_avaliable=capacity_avaliable,
account_balance=format(account_balance, '.2f'), account_balance=format(account_balance, '.2f'),
ssh_public_keys=ssh_public_keys, ssh_public_keys=ssh_public_keys,
@ -209,6 +222,9 @@ def ssh_public_keys():
errors = list() errors = list()
if request.method == "POST": if request.method == "POST":
if "csrf-token" not in request.form or request.form['csrf-token'] != session['csrf-token']:
return abort(418, f"u want tea")
method = request.form["method"] method = request.form["method"]
content = None content = None
@ -223,7 +239,6 @@ def ssh_public_keys():
else: else:
errors.append("Name is required") errors.append("Name is required")
if not re.match(r"^[0-9A-Za-z_@. -]+$", name): if not re.match(r"^[0-9A-Za-z_@. -]+$", name):
print(name)
errors.append("Name must match \"^[0-9A-Za-z_@. -]+$\"") errors.append("Name must match \"^[0-9A-Za-z_@. -]+$\"")
if method == "POST": if method == "POST":
@ -254,7 +269,12 @@ def ssh_public_keys():
get_model().list_ssh_public_keys_for_account(session["account"]) get_model().list_ssh_public_keys_for_account(session["account"])
)) ))
return render_template("ssh-public-keys.html", ssh_public_keys=keys_list, has_ssh_public_keys=len(keys_list) > 0) return render_template(
"ssh-public-keys.html",
csrf_token = session["csrf-token"],
ssh_public_keys=keys_list,
has_ssh_public_keys=len(keys_list) > 0
)
def get_vms(): def get_vms():
if 'user_vms' not in g: if 'user_vms' not in g:

View File

@ -24,6 +24,7 @@
<form id="delete_action" method="post"> <form id="delete_action" method="post">
<input type="hidden" name="delete" value="True"/> <input type="hidden" name="delete" value="True"/>
<input type="hidden" name="are_you_sure" value="True"/> <input type="hidden" name="are_you_sure" value="True"/>
<input type="hidden" name="csrf-token" value="{{ csrf_token }}"/>
<input type="submit" class="form-submit-link" value="Yes, Delete"> <input type="submit" class="form-submit-link" value="Yes, Delete">
</form> </form>
</div> </div>
@ -79,6 +80,7 @@
<label class="align" for="delete_action">Actions</label> <label class="align" for="delete_action">Actions</label>
<form id="delete_action" method="post"> <form id="delete_action" method="post">
<input type="hidden" name="delete" value="True"/> <input type="hidden" name="delete" value="True"/>
<input type="hidden" name="csrf-token" value="{{ csrf_token }}"/>
<input type="submit" class="form-submit-link" value="Delete..."> <input type="submit" class="form-submit-link" value="Delete...">
</form> </form>
</div> </div>

View File

@ -37,6 +37,7 @@
{% else %} {% else %}
<form method="post"> <form method="post">
<input type="hidden" name="csrf-token" value="{{ csrf_token }}"/>
<div class="row justify-start"> <div class="row justify-start">
<label class="align" for="size">Capsul Size</label> <label class="align" for="size">Capsul Size</label>
<select id="size" name="size"> <select id="size" name="size">

View File

@ -13,6 +13,7 @@
<form method="post"> <form method="post">
<input type="hidden" name="method" value="DELETE"></input> <input type="hidden" name="method" value="DELETE"></input>
<input type="hidden" name="name" value="{{ ssh_public_key['name'] }}"></input> <input type="hidden" name="name" value="{{ ssh_public_key['name'] }}"></input>
<input type="hidden" name="csrf-token" value="{{ csrf_token }}"/>
<div class="row"> <div class="row">
<span class="code">{{ ssh_public_key['name'] }}</span> <span class="code">{{ ssh_public_key['name'] }}</span>
<span class="dim">{{ ssh_public_key['content'] }}</span> <span class="dim">{{ ssh_public_key['content'] }}</span>
@ -28,6 +29,7 @@
</div> </div>
<form method="post"> <form method="post">
<input type="hidden" name="method" value="POST"></input> <input type="hidden" name="method" value="POST"></input>
<input type="hidden" name="csrf-token" value="{{ csrf_token }}"/>
<div class="row justify-start"> <div class="row justify-start">
<label class="align" for="content">File Contents</label> <label class="align" for="content">File Contents</label>
<textarea class="expand" id="content" name="content"></textarea> <textarea class="expand" id="content" name="content"></textarea>