Fixing CSRF issues and expanding trusted proxies to local network

selenium-screenshot-testing
CodeKevin 2016-02-06 15:38:14 -05:00
parent c336ad6fd1
commit 1dcba3a264
4 changed files with 38 additions and 27 deletions

View File

@ -60,6 +60,7 @@
<button type="submit" id="submit" tabindex="5" class="btn btn-md btn-theme btn-outlined pull-right">Submit</button> <button type="submit" id="submit" tabindex="5" class="btn btn-md btn-theme btn-outlined pull-right">Submit</button>
</div> </div>
</div> </div>
<input type="hidden" name="nonce" value="{{ nonce }}">
</form> </form>
</div> </div>
</div> </div>

View File

@ -56,6 +56,7 @@
<button type="submit" id="submit" tabindex="5" class="btn btn-md btn-theme btn-outlined pull-right">Submit</button> <button type="submit" id="submit" tabindex="5" class="btn btn-md btn-theme btn-outlined pull-right">Submit</button>
</div> </div>
</div> </div>
<input type="hidden" name="nonce" value="{{ nonce }}">
</form> </form>
</div> </div>
</div> </div>

View File

@ -1,9 +1,9 @@
from CTFd.models import db, WrongKeys, Pages, Config from CTFd.models import db, WrongKeys, Pages, Config, Tracking
from CTFd import mail from CTFd import mail
from six.moves.urllib.parse import urlparse, urljoin from six.moves.urllib.parse import urlparse, urljoin
from functools import wraps from functools import wraps
from flask import current_app as app, g, request, redirect, url_for, session, render_template from flask import current_app as app, g, request, redirect, url_for, session, render_template, abort
from flask.ext.mail import Message from flask.ext.mail import Message
from socket import inet_aton, inet_ntoa from socket import inet_aton, inet_ntoa
from struct import unpack, pack from struct import unpack, pack
@ -18,6 +18,7 @@ import requests
import logging import logging
import os import os
import sys import sys
import re
def init_logs(app): def init_logs(app):
@ -78,6 +79,7 @@ def init_errors(app):
def gateway_error(error): def gateway_error(error):
return render_template('errors/502.html'), 502 return render_template('errors/502.html'), 502
def init_utils(app): def init_utils(app):
app.jinja_env.filters['unix_time'] = unix_time app.jinja_env.filters['unix_time'] = unix_time
app.jinja_env.filters['unix_time_millis'] = unix_time_millis app.jinja_env.filters['unix_time_millis'] = unix_time_millis
@ -89,7 +91,7 @@ def init_utils(app):
@app.context_processor @app.context_processor
def inject_user(): def inject_user():
if authed(): if session:
return dict(session) return dict(session)
return dict() return dict()
@ -100,6 +102,27 @@ def init_utils(app):
if not is_setup(): if not is_setup():
return redirect(url_for('views.setup')) return redirect(url_for('views.setup'))
@app.before_request
def tracker():
if authed():
track = Tracking.query.filter_by(ip=ip2long(get_ip()), team=session['id']).first()
if not track:
visit = Tracking(ip=get_ip(), team=session['id'])
db.session.add(visit)
db.session.commit()
else:
track.date = datetime.datetime.utcnow()
db.session.commit()
db.session.close()
@app.before_request
def csrf():
if not session.get('nonce'):
session['nonce'] = sha512(os.urandom(10))
if request.method == "POST":
if session['nonce'] != request.form.get('nonce'):
abort(403)
def ctf_name(): def ctf_name():
name = get_config('ctf_name') name = get_config('ctf_name')
@ -207,11 +230,18 @@ def unix_time_millis(dt):
def get_ip(): def get_ip():
trusted_proxies = {'127.0.0.1'} # define your own set trusted_proxies = [
'^127\.0\.0\.1$',
'^::1$',
'^fc00:',
'^10\.',
'^172\.(1[6-9]|2[0-9]|3[0-1])\.',
'^192\.168\.'
]
combined = "(" + ")|(".join(trusted_proxies) + ")"
route = request.access_route + [request.remote_addr] route = request.access_route + [request.remote_addr]
remote_addr = next((addr for addr in reversed(route) remote_addr = next((addr for addr in reversed(route) if re.match(combined, addr)), request.remote_addr)
if addr not in trusted_proxies), request.remote_addr)
return remote_addr return remote_addr

View File

@ -17,27 +17,6 @@ import datetime
views = Blueprint('views', __name__) views = Blueprint('views', __name__)
@views.before_request
def tracker():
if authed():
track = Tracking.query.filter_by(ip=ip2long(get_ip()), team=session['id']).first()
if not track:
visit = Tracking(ip=get_ip(), team=session['id'])
db.session.add(visit)
db.session.commit()
else:
track.date = datetime.datetime.utcnow()
db.session.commit()
db.session.close()
@views.before_request
def csrf():
if request.method == "POST":
if session['nonce'] != request.form.get('nonce'):
abort(403)
@views.before_request @views.before_request
def redirect_setup(): def redirect_setup():
if request.path == "/static/css/style.css": if request.path == "/static/css/style.css":