Skip to content

Commit 1f5634e

Browse files
authored
bug fixes, upgrade deps, security fixes (#75)
* Update README.md * Update CONTRIBUTING.md * fixes and more strict security headers
1 parent a426638 commit 1f5634e

File tree

11 files changed

+37
-30
lines changed

11 files changed

+37
-30
lines changed

.dockerignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ venv/
33
*.pyc
44
.vscode/
55
*.db
6-
.idea/
6+
.idea/
7+
.github/

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ install:
2121
- "pip install -r src/requirements.txt"
2222
- "python src/create_db.test.py"
2323

24-
before_script:
25-
- black . --check
2624
script:
25+
- black . --check
2726
- flake8 . --count --max-line-length=88 --show-source --statistics

app.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616
}
1717
],
1818
"env": {
19-
"SECRET_KEY": {
20-
"description": "Flask app instance's SECRET_KEY",
21-
"generator": "secret"
22-
},
2319
"ADMIN_PASS": {
2420
"description": "Administrator password",
2521
"generator": "secret"

docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ services:
88
- "8000"
99
environment:
1010
- DEBUG=False
11-
- SECRET_KEY=changeme
11+
- SSL_ENABLED=False
1212
- DB_USER=eshaan
1313
- DB_PASSWORD=eshaan
1414
- DB_NAME=rtbctf
1515
- DB_PORT=5432
16-
- WORKERS=8
16+
- WORKERS=4
1717
- ADMIN_PASS=admin
1818
depends_on:
1919
- postgres

src/FlaskRTBCTF/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
admin_manager,
1212
mail,
1313
inject_app_context,
14+
inject_security_headers,
1415
)
1516
from FlaskRTBCTF.users.routes import users
1617
from FlaskRTBCTF.ctf.routes import ctf
@@ -26,6 +27,7 @@ def create_app(config_class=Config):
2627
app = Flask(__name__)
2728
app.config.from_object(Config)
2829
app.context_processor(inject_app_context)
30+
app.after_request(inject_security_headers)
2931

3032
for _ext in _extensions:
3133
_ext.init_app(app)

src/FlaskRTBCTF/config.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
import os
2-
3-
from .utils import handle_secret_key
2+
import secrets
43

54
# Flask related Configurations
65
# Note: DO NOT FORGET TO CHANGE 'SECRET_KEY' !
76

87

98
class Config:
10-
DEBUG = True # Turn DEBUG OFF before deployment
11-
SECRET_KEY = handle_secret_key()
9+
DEBUG = False # Turn DEBUG OFF before deployment
10+
SECRET_KEY = secrets.token_hex(16)
1211
SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URL") or "sqlite:///site.db"
1312
# For local use, one can simply use SQLlite with: 'sqlite:///site.db'
1413
# For deployment on Heroku use: `os.environ.get('DATABASE_URL')`
1514
# in all other cases: `os.environ.get('SQLALCHEMY_DATABASE_URI')`
1615
SQLALCHEMY_TRACK_MODIFICATIONS = False
1716
FLASK_ADMIN_SWATCH = ("journal", "paper", "yeti", "cosmo")[3]
1817
# TEMPLATES_AUTO_RELOAD = True
18+
# Session handling
19+
SESSION_COOKIE_HTTPONLY = True
20+
SESSION_COOKIE_SAMESITE = "Strict"
21+
SESSION_COOKIE_SECURE = (
22+
True if os.environ.get("SSL_ENABLED", False) == "True" else False
23+
)
1924
MAIL_SERVER = "smtp.googlemail.com"
2025
MAIL_PORT = 587
2126
MAIL_USE_TLS = True

src/FlaskRTBCTF/main/forms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ def setup(self):
2929
try:
3030
settings = Settings.query.get(1)
3131

32+
settings.dummy = False
3233
settings.ctf_name = self.ctf_name.data
3334
settings.organization_name = self.organization_name.data
3435
settings.from_date = self.from_date.data
3536
settings.from_time = self.from_time.data
3637
settings.to_date = self.to_date.data
3738
settings.to_time = self.to_time.data
38-
settings.dummy = False
3939

4040
db.session.commit()
4141

src/FlaskRTBCTF/templates/layout.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
77
<meta http-equiv="X-UA-Compatible" content="ie=edge">
88
<!-- Favicon -->
9-
<link rel='shortcut icon' type='image/x-icon' href="{{ url_for('static', filename='favicon.ico')}}"/>
9+
<link rel="shortcut icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico')}}"/>
1010
<!-- Bootstrap CSS -->
1111
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
1212
<!-- Font Awesome -->
@@ -88,7 +88,13 @@ <h3>{{ settings.organization_name }}</h3>
8888
<p class="text-muted">
8989
<ul class="list-group">
9090
{% for w in websites %}
91-
<a target="_blank" href="{{ w.url }}" class="list-group-item list-group-item-action">{{ w.name }}</a>
91+
<a target="_blank"
92+
href="{{ w.url }}"
93+
class="list-group-item list-group-item-action"
94+
rel="noreferrer noopener"
95+
>
96+
{{ w.name }}
97+
</a>
9298
{% endfor %}
9399
</ul>
94100
</p>

src/FlaskRTBCTF/utils/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
from .helpers import (
66
handle_admin_pass,
77
handle_admin_email,
8-
handle_secret_key,
98
is_past_running_time,
109
inject_app_context,
10+
inject_security_headers,
1111
clear_points_cache,
1212
clear_rating_cache,
1313
)

src/FlaskRTBCTF/utils/helpers.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,6 @@
1010
from ..main.models import Settings, Website
1111

1212

13-
def handle_secret_key(default="you-will-never-guess"):
14-
sk = os.environ.get("SECRET_KEY", default)
15-
if not sk:
16-
sk = secrets.token_hex(16)
17-
os.environ["SECRET_KEY"] = sk
18-
return sk
19-
20-
2113
def handle_admin_pass(default="admin"):
2214
passwd = os.environ.get("ADMIN_PASS", default)
2315
if not passwd:
@@ -40,6 +32,14 @@ def inject_app_context():
4032
return dict(settings=settings, websites=websites)
4133

4234

35+
def inject_security_headers(response):
36+
response.headers["X-Frame-Options"] = "SAMEORIGIN"
37+
# response.headers["Content-Security-Policy"] = "default-src 'self'"
38+
response.headers["X-Content-Type-Options"] = "nosniff"
39+
response.headers["X-XSS-Protection"] = "1; mode=block"
40+
return response
41+
42+
4343
@cache.cached(timeout=60, key_prefix="past_running_time")
4444
def is_past_running_time():
4545
end_date_time = Settings.get_settings().running_time_to

0 commit comments

Comments
 (0)