diff --git a/frontend.py b/frontend.py index 452769f..7fbf975 100755 --- a/frontend.py +++ b/frontend.py @@ -178,9 +178,10 @@ def register_telegram(user): return city_page(user.get_city(), info="Thanks for registering Telegram!") -@get('/api/state') -def api_enable(user): - return user.state() +# unused afaik +#@get('/api/state') +#def api_enable(user): +# return user.state() @get('/static/<filename:path>') @@ -197,6 +198,7 @@ def guides(filename): def logout(): # clear auth cookie response.set_cookie('uid', '', expires=0, path="/") + response.set_cookie('csrf', '', expires=0, path="/") # :todo show info "Logout successful." redirect('/') diff --git a/photo-1461685265823-f8d5d0b08b9b?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&dl=matthew-henry-87142-unsplash.jpg b/photo-1461685265823-f8d5d0b08b9b?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&dl=matthew-henry-87142-unsplash.jpg deleted file mode 100644 index 1b546db..0000000 Binary files a/photo-1461685265823-f8d5d0b08b9b?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&dl=matthew-henry-87142-unsplash.jpg and /dev/null differ diff --git a/session.py b/session.py index 5d0c263..ccda7bb 100644 --- a/session.py +++ b/session.py @@ -1,4 +1,4 @@ -from bottle import redirect, request +from bottle import redirect, request, abort, response from db import db from functools import wraps from inspect import Signature @@ -17,10 +17,14 @@ class SessionPlugin(object): if self.keyword in Signature.from_callable(route.callback).parameters: @wraps(callback) def wrapper(*args, **kwargs): - uid = request.get_cookie('uid', secret=db.secret) + uid = request.get_cookie('uid', secret=db.get_secret()) if uid is None: return redirect(self.loginpage) kwargs[self.keyword] = User(uid) + if request.method == 'POST': + if request.forms['csrf'] != request.get_cookie('csrf', + secret=db.get_secret()): + abort(400) return callback(*args, **kwargs) return wrapper diff --git a/template/settings.tpl b/template/settings.tpl index dae30ce..66cf873 100644 --- a/template/settings.tpl +++ b/template/settings.tpl @@ -61,6 +61,7 @@ <option value='octodon.social'> <option value='soc.ialis.me'> </datalist> + <input name='csrf' value='{{csrf}}' type='hidden' /> <input name='confirm' value='Log in' type='submit'/> </form> </section> @@ -82,6 +83,7 @@ </p> <form action="/settings/telegram" method="post"> <input type="text" name="apikey" placeholder="Telegram bot API key" id="apikey"> + <input name='csrf' value='{{csrf}}' type='hidden' /> <input name='confirm' value='Login with Telegram' type='submit'/> </form> </div> @@ -106,6 +108,7 @@ </p> <form action="/settings/markdown" method="post"> <textarea id="markdown" rows="20" cols="70" name="markdown" wrap="physical">{{markdown}}</textarea> + <input name='csrf' value='{{csrf}}' type='hidden' /> <input name='confirm' value='Save' type='submit'/> </form> </div> @@ -123,6 +126,7 @@ </p> <form action="/settings/mail_md" method="post"> <textarea id="mail_md" rows="20" cols="70" name="mail_md" wrap="physical">{{mail_md}}</textarea> + <input name='csrf' value='{{csrf}}' type='hidden' /> <input name='confirm' value='Save' type='submit'/> </form> </div> @@ -137,6 +141,7 @@ </p> <form action="/settings/goodlist" method="post"> <textarea id="goodlist" rows="8" cols="70" name="goodlist" wrap="physical">{{triggerwords}}</textarea> + <input name='csrf' value='{{csrf}}' type='hidden' /> <input name='confirm' value='Submit' type='submit'/> </form> </div> @@ -151,6 +156,7 @@ </p> <form action="/settings/blocklist" method="post"> <textarea id="blocklist" rows="8" cols="70" name="blocklist" wrap="physical">{{badwords}}</textarea> + <input name='csrf' value='{{csrf}}' type='hidden' /> <input name='confirm' value='Submit' type='submit'/> </form> </div> diff --git a/user.py b/user.py index 92eb463..147fb40 100644 --- a/user.py +++ b/user.py @@ -1,9 +1,10 @@ from config import config -from bottle import response +from bottle import response, request from db import db import jwt from mastodon import Mastodon from pylibscrypt import scrypt_mcf, scrypt_mcf_check +from os import urandom class User(object): @@ -11,6 +12,13 @@ class User(object): # set cookie response.set_cookie('uid', uid, secret=db.get_secret(), path='/') self.uid = uid + response.set_cookie('csrf', self.get_csrf(), db.get_secret(), path='/') + + def get_csrf(self): + csrf_token = request.get_cookie('csrf', secret=db.get_secret()) + if not csrf_token: + csrf_token = str(urandom(32)) + return csrf_token def check_password(self, password): db.execute("SELECT passhash FROM user WHERE id=?;", (self.uid,)) @@ -235,6 +243,7 @@ schlitz # - mail_md # - goodlist # - blocklist + # - csrf # - logged in with twitter? # - logged in with mastodon? # - enabled? @@ -244,7 +253,8 @@ schlitz mail_md=citydict['mail_md'], triggerwords=self.get_trigger_words(), badwords=self.get_badwords(), - enabled=self.enabled) + enabled=self.enabled, + csrf=self.get_csrf()) def save_request_token(self, token): db.execute("""INSERT INTO