Merge pull request #82 from ticketfrei/csrf
Building in CSRF prevention
This commit is contained in:
commit
02f117a864
|
@ -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('/')
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
14
user.py
14
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
|
||||
|
|
Loading…
Reference in a new issue