Skip to content

Instantly share code, notes, and snippets.

@LukasForst
Created November 9, 2022 10:15
Show Gist options
  • Save LukasForst/421c089f20ae039052b31c68d21953d5 to your computer and use it in GitHub Desktop.
Save LukasForst/421c089f20ae039052b31c68d21953d5 to your computer and use it in GitHub Desktop.
Insecure flask - session not signed
import base64
import json
import time
from functools import wraps
from flask import Flask, request, make_response
app = Flask(__name__)
books = {
"1": {
"name": "Book #1",
"owner": "user_a"
},
"2": {
"name": "Book #2",
"owner": "user_b"
},
"3": {
"name": "Book #3",
"owner": "user_a"
},
"4": {
"name": "Book #4",
"owner": "user_b"
},
"5": {
"name": "Book #5",
"owner": "user_c"
},
"6": {
"name": "Book #6",
"owner": "user_c"
},
}
users = {
"user_a": "some_password",
"user_b": "different_password"
}
def encode_session(user: str, timestamp: float) -> str:
s = json.dumps({'user': user, 'valid': timestamp})
return base64.b64encode(s.encode()).decode()
def decode_session(s: str) -> dict:
b = base64.b64decode(s.encode()).decode()
return json.loads(b)
def get_user_from_session() -> str:
return decode_session(request.cookies.get('session'))['user']
def require_session(f):
@wraps(f)
def decorated(*args, **kwargs):
maybe_session = request.cookies.get('session', None)
try:
maybe_session = decode_session(maybe_session) if maybe_session else None
if not maybe_session:
return {'message': 'unauthorized'}, 401
elif maybe_session['valid'] < time.time():
return {'message': 'session expired'}, 401
return f(*args, **kwargs)
except:
return {'message': 'unauthorized'}, 401
return decorated
@app.route("/book/", methods=['GET'])
@require_session
def get_books():
user = get_user_from_session()
return {'books': [b for _, b in books.items() if b['owner'] == user]}
@app.route("/book/<book_id>", methods=['GET'])
@require_session
def get_book(book_id):
book = books[book_id]
if not book:
return {'message': 'book not found'}, 404
elif book['owner'] != get_user_from_session():
return {'message': 'Book does not belong to you!'}, 403
else:
return book
@app.route("/login", methods=['POST'])
def login():
body = request.json
try:
user = body['username']
if body['password'] == users.get(user, None):
resp = make_response({'user': user})
resp.headers['set-cookie'] = encode_session(user, time.time() + 600)
return resp
except:
pass
return {'message': 'unauthorized'}, 401
if __name__ == '__main__':
app.run(debug=True, port=8080)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment