-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Benjamin Trapp
committed
Apr 16, 2017
1 parent
c14913b
commit 60a2b68
Showing
20 changed files
with
477 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -87,3 +87,4 @@ ENV/ | |
|
||
# Rope project settings | ||
.ropeproject | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
from flask import Flask, request, render_template, redirect, url_for, session, flash | ||
from random import choice, random | ||
from ServerSideSession import VolatileServerSideSessionInterface | ||
from uuid import uuid4 | ||
|
||
import string | ||
|
||
ORDER_ARTICLE_INITIAL_STEP = 1 | ||
ORDER_ARTICLE_WORKFLOW_STEPS = 4 | ||
|
||
uuid = uuid4 | ||
|
||
app = Flask(__name__) | ||
app.session_interface = VolatileServerSideSessionInterface() | ||
|
||
__users = {'user': 'hallo'} | ||
__max_notes = 3 | ||
__articles = [(1, 'Article1'), | ||
(2, 'Article2'), | ||
(3, 'Article3')] | ||
|
||
|
||
@app.route('/') | ||
def home(): | ||
return render_template("home.html") | ||
|
||
|
||
@app.route('/login', methods = ['POST', 'GET']) | ||
def login(): | ||
if __is_login_session(): | ||
return redirect(url_for('home')) | ||
|
||
if request.method == 'GET': | ||
return render_template("login.html") | ||
elif request.method == 'POST': | ||
username = request.form['user'] | ||
|
||
try: | ||
password = __users[username] | ||
except KeyError: | ||
return render_template("login.html", message = "User " + username + " unknown!") | ||
|
||
if password == request.form['pass']: | ||
session['user'] = username | ||
__new_csrf_token() | ||
if 'redirectto' in request.form: | ||
return redirect(url_for(request.form['redirectto'])) | ||
else: | ||
return render_template("login.html", message = "Login failed!") | ||
|
||
|
||
@app.route('/logout') | ||
def logout(): | ||
session.clear() | ||
return render_template("login.html", message = "You have successfully logged out.") | ||
|
||
|
||
@app.route('/CSRFProtected', methods = ['POST', 'GET']) | ||
def CSRFProtection(): | ||
if not __is_login_session(): | ||
return redirect(url_for('login', redirectto = 'CSRFProtection')) | ||
|
||
if request.method == 'GET': | ||
return render_template("CSRFForm.html") | ||
elif request.method == 'POST': | ||
if not __csrf_validation(): | ||
return render_template("message.html", message = "CSRF validation failed!") | ||
else: | ||
return render_template("CSRFShow.html") | ||
|
||
|
||
@app.route('/ProbabilisticLogout', methods = ['POST', 'GET']) | ||
def ProbabilisticLogout(): | ||
if not __is_login_session(): | ||
return redirect(url_for('login', redirectto = 'ProbabilisticLogout')) | ||
|
||
if request.method == 'GET': | ||
return render_template("ProbForm.html", fields = list(string.ascii_lowercase)) | ||
elif request.method == 'POST': | ||
if random() < 0.2: | ||
return logout() | ||
else: | ||
if __csrf_validation(): | ||
return render_template("ProbShow.html", fields = list(string.ascii_lowercase)) | ||
else: | ||
return render_template("message.html", message = "CSRF validation failed!") | ||
|
||
|
||
@app.route('/OrderArticle/<int:step>', methods = ['POST', 'GET']) | ||
def OrderArticle(step): | ||
if not __is_login_session(): | ||
return redirect(url_for('login', redirectto = 'ProbabilisticLogout')) | ||
|
||
if 'step' not in session: | ||
session['step'] = ORDER_ARTICLE_INITIAL_STEP | ||
|
||
if session['step'] < step: | ||
return render_template("message.html", message = "Order Article request doesn't match the OrderArticle state!") | ||
|
||
if session['step'] != step: | ||
session['step'] = step | ||
|
||
if request.method == 'GET': | ||
return render_template("OrderArticle-Step{}.html".format(step), articles = __articles) | ||
elif request.method == 'POST': | ||
if not __csrf_validation(): | ||
return render_template("message.html", message = "CSRF validation failed!") | ||
|
||
if step < ORDER_ARTICLE_WORKFLOW_STEPS: | ||
for param in request.form: | ||
session['wf_' + param] = request.form[param] | ||
|
||
session['step'] += 1 | ||
return redirect(url_for('OrderArticle', step = session['step'])) | ||
else: | ||
session['step'] = 1 | ||
return render_template("message.html", message = "Thanks for your order! " | ||
"Your article will be delivered soon!") | ||
|
||
|
||
@app.route('/Notes', methods = ['POST', 'GET']) | ||
def Notes(): | ||
if not __is_login_session(): | ||
return redirect(url_for('login', redirectto = 'Notes')) | ||
|
||
if 'notes' not in session: | ||
session['notes'] = dict() | ||
|
||
if request.method == 'GET': | ||
pass | ||
|
||
if request.method == 'POST': | ||
if request.form['action'] == 'add': | ||
if len(session['notes']) >= __max_notes: | ||
flash("No more notes allowed!") | ||
else: | ||
note = {'subject': request.form['subject'], 'content': request.form['content']} | ||
session['notes'][str(uuid())] = note | ||
flash("Note was added") | ||
|
||
if request.form['action'] == 'delete': | ||
nid = request.form['id'] | ||
if nid in session['notes']: | ||
subject = session['notes'][nid]['subject'] | ||
del session['notes'][nid] | ||
flash("Note '%s' deleted" % (subject)) | ||
else: | ||
flash("Note with id '%s' doesn\'t exists" % nid) | ||
|
||
return render_template("notes.html", notes = session['notes']) | ||
|
||
|
||
def __is_login_session(): | ||
return 'user' in session | ||
|
||
|
||
def __new_csrf_token(): | ||
session['csrftoken'] = "".join([choice(string.ascii_letters) for i in range(32)]) | ||
|
||
|
||
def __csrf_validation(): | ||
try: | ||
__session_token = session['csrftoken'] | ||
__new_csrf_token() | ||
return __session_token == request.form['csrftoken'] | ||
except: | ||
return False | ||
|
||
if __name__ == '__main__': | ||
app.run(port = 8001, debug = False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from flask.sessions import SessionInterface, SessionMixin | ||
from uuid import uuid4 | ||
uuid = uuid4 | ||
|
||
#################################################################################### | ||
# !!! WARNING !!! # | ||
# This session management implementation contains vulnerabilities only for # | ||
# Demonstration. DON'T USE IT IN PRODUCTION! # | ||
#################################################################################### | ||
|
||
|
||
class VolatileServerSideSessionInterface(SessionInterface): | ||
cookie_name = "vsessid" | ||
sessions = dict() | ||
|
||
def open_session(self, app, request): | ||
sid = request.cookies.get(self.cookie_name) | ||
|
||
if not sid: | ||
sid = str(uuid()) | ||
|
||
if sid not in self.sessions: | ||
self.sessions[sid] = VolatileServerSideSession(sid) | ||
|
||
return self.sessions[sid] | ||
|
||
def save_session(self, app, session, response): | ||
if not session.sid: | ||
response.delete_cookie(self.cookie_name) | ||
elif session.new: | ||
response.set_cookie(self.cookie_name, session.sid) | ||
session.new = False | ||
|
||
|
||
class VolatileServerSideSession(dict, SessionMixin): | ||
def __init__(self, sid): | ||
self.sid = sid | ||
self.new = True |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
body { | ||
background-color: #708090;/*#293133;*/ | ||
color: #222222; | ||
} | ||
|
||
.logo { | ||
float: left; | ||
font-weight: bold; | ||
font-size: 20px; | ||
color: red; | ||
} | ||
|
||
a:link, a:visited { | ||
color: white; | ||
} | ||
|
||
.header { | ||
display: block; | ||
text-align: right; | ||
color: white; | ||
background-color: black; | ||
padding: 8px; | ||
} | ||
|
||
.content { | ||
background-color: darkgrey; | ||
padding: 15px; | ||
margin: 15px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
<form action="/CSRFProtected" method="POST"> | ||
Input: <input name="input"> | ||
<input type="hidden" name="csrftoken" value="{{ session['csrftoken'] }}"> | ||
<input type="submit" value="Go"> | ||
</form> | ||
{% endblock %} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
Got this: {{ request.form["input"] | safe }}<br> | ||
<a href="/CSRFProtected">Back to form</a> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
Select article: | ||
<form action="/OrderArticle/1" method="POST"> | ||
<select name="choice" size="1"> | ||
{% for article in articles %} | ||
<option value="{{ article[0] }}">{{ article[1] }}</option> | ||
{% endfor %} | ||
</select> | ||
<input type="hidden" name="csrftoken" value="{{ session['csrftoken'] }}"> | ||
<input type="submit" value="Next"> | ||
</form> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
<h1>Deliver to</h1> | ||
<form action="/OrderArticle/2" method="POST"> | ||
<table> | ||
<tr><td>Name</td><td><input name="name1"><input name="name2"></td></tr> | ||
<tr><td>Street</td><td><input name="street"><input name="num"></td></tr> | ||
<tr><td>Zip/City</td><td><input name="zip"><input name="city"></td></tr> | ||
</table> | ||
<input type="hidden" name="csrftoken" value="{{ session['csrftoken'] }}"> | ||
<input type="submit" value="Next"> | ||
</form> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
<h1>Payment</h1> | ||
<form action="/OrderArticle/3" method="POST"> | ||
<table> | ||
<tr><td>IBAN</td><td><input name="iban"></td></tr> | ||
<tr><td>BIC</td><td><input name="bic"></td></tr> | ||
<tr><td>Bank</td><td><input name="bank"></td></tr> | ||
<tr><td>Account Owner</td><td><input name="owner"></td></tr> | ||
</table> | ||
<input type="hidden" name="csrftoken" value="{{ session['csrftoken'] }}"> | ||
<input type="submit" value="Next"> | ||
</form> | ||
{% endblock %} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
<h1>Check and Confirm</h1> | ||
<form action="/OrderArticle/4" method="POST"> | ||
<table> | ||
<tr><td>Selected Article</td><td>{{ articles[session['wf_choice']] }}</td></tr> | ||
<tr><td>Deliver to</td><td>{{ session['wf_name1'] }} {{ session['wf_name2'] }}, {{ session['wf_street'] | safe }} {{ session['wf_num'] }}, {{ session['wf_zip'] }} {{ session['wf_city'] }}</td></tr> | ||
<tr><td>Payment Details</td><td>IBAN: {{ session['wf_iban'] }}, BIC: {{ session['wf_bic'] }}, {{ session['wf_bank'] }}, {{ session['wf_owner'] }}</td></tr> | ||
</table> | ||
<input type="hidden" name="csrftoken" value="{{ session['csrftoken'] }}"> | ||
<input type="submit" value="Confirm"> | ||
</form> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
Please submit form:<br> | ||
<form action="/ProbabilisticLogout" method="POST"> | ||
<table> | ||
{% for field in fields %} | ||
<tr><td>Field {{ field | upper }}</td><td><input name="{{ field }}"></td></tr> | ||
{% endfor %} | ||
</table> | ||
<input type="hidden" name="csrftoken" value="{{ session['csrftoken'] }}"> | ||
<input type="submit" value="Go"> | ||
</form> | ||
{% endblock %} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
Got this:<br> | ||
<table> | ||
{% for field in fields %} | ||
{% if field == "q" %} | ||
<tr><td>Field {{ field | upper }}:</td><td>{{ request.form[field] | safe }}</td></tr> | ||
{% else %} | ||
<tr><td>Field {{ field | upper }}:</td><td>{{ request.form[field] }}</td></tr> | ||
{% endif %} | ||
{% endfor %} | ||
</table> | ||
<a href="/ProbabilisticLogout">Back to form</a> | ||
{% endblock %} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<title>Project Makalu - Broken Session Handling Shop</title> | ||
<link rel="stylesheet" href="/static/style.css"> | ||
<link rel="icon" href="/static/favicon.ico" /> | ||
</head> | ||
<body> | ||
<div class="header"> | ||
<div class="logo" align="left">anna group</div> | ||
<a href="/">Home</a> | ||
{% if session['user'] %} | ||
<a href="/logout">Logout</a> (Logged in as {{ session['user'] }}) | ||
{% else %} | ||
<a href="/login">Login</a> | ||
{% endif %} | ||
</div> | ||
<div class="content"> | ||
{% block content %}{% endblock %} | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
<a href="/CSRFProtected">CSRF Protection</a><br> | ||
<a href="/ProbabilisticLogout">Probabilistic Logout</a><br> | ||
<a href="/OrderArticle/1">Order an Article</a><br> | ||
<a href="/Notes">Notes</a> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{% extends "app.html" %} | ||
{% block content %} | ||
<h1>Login</h1> | ||
<form action="/login" method="POST"> | ||
Username: <input type="text" name="user"><br> | ||
Password: <input type="password" name="pass"><br> | ||
<input type="hidden" name="redirectto" value="{{ request.args.get('redirectto') or 'home' }}"> | ||
<input type="submit" value="Login"> | ||
</form> | ||
<br> | ||
<div style="color: red;">{{ message }}</div><br> | ||
{% endblock %} |
Oops, something went wrong.