]>
git.gir.st - subscriptionfeed.git/blob - app/__init__.py
3 from flask
import Flask
5 from .common
.common
import *
8 app
.secret_key
= base64
.b64decode(cf
['frontend'].get('secret_key','')) or \
9 secrets
.token_bytes(16) # development fallback; CSRF/cookies won't persist.
11 from .common
.user
import init_login
15 app
.register_blueprint(youtube
.frontend
)
18 app
.register_blueprint(reddit
.frontend
)
20 # TODO: build a proper flask extension
21 # Magic CSRF protection: This modifies outgoing HTML responses and injects a csrf token into all forms.
22 # All post requests are then checked if they contain the valid token.
24 # - don't use regex for injecting
25 # - inject a http header into all responses (that could be used by apis)
26 # - allow csrf token to be passed in http header, json, ...
27 # - a decorator on routes to opt out of verification or output munging
28 # https://stackoverflow.com/questions/19574694/flask-hit-decorator-before-before-request-signal-fires
29 # - allow specifying hmac message contents (currently request.remote_addr)
33 from flask
import request
35 def add_csrf_protection(response
):
36 if response
.mimetype
== "text/html":
37 token
= hmac
.new(app
.secret_key
, request
.remote_addr
.encode('ascii'), hashlib
.sha256
).hexdigest() # TODO: will fail behind reverse proxy (remote_addr always localhost)
38 response
.set_data( re
.sub(
39 rb
'''(<[Ff][Oo][Rr][Mm](\s+[a-zA-Z0-9-]+(=(\w*|'[^']*'|"[^"]*"))?)*>)''', # match form tags with any number of attributes and any type of quotes
40 rb
'\1<input type="hidden" name="csrf" value="'+token
.encode('ascii')+rb
'">', # hackily append a hidden input with our csrf protection value
44 def verify_csrf_protection():
45 token
= hmac
.new(app
.secret_key
, request
.remote_addr
.encode('ascii'), hashlib
.sha256
).hexdigest() # TODO: will fail behind reverse proxy (remote_addr always localhost)
46 if request
.method
== "POST" and request
.form
.get('csrf') != token
:
47 return "CSRF validation failed!", 400
48 request
.form
= request
.form
.copy() # make it mutable
49 request
.form
.poplist('csrf') # remove our csrf again