From a47bcbdfbd03f03efe3cd875ab695ad092feeb04 Mon Sep 17 00:00:00 2001 From: saaa99999999 Date: Sat, 16 May 2026 18:25:35 +0800 Subject: [PATCH] fix: 3 security vulnerabilities - CWE-798: Remove hardcoded SECRET_KEY fallback, require env var - CWE-639: Add bookerId ownership check to /cancelbooking (IDOR fix) - CWE-601: Fix open redirect bypass in /login (http:/evil.com) Reported by security review. See advisory at https://github.com/saaa99999999/room-booking-app/security/advisories --- app/routes.py | 14 ++++++++++++-- config.py | 7 ++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/routes.py b/app/routes.py index 94893e1..b90bd2b 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,4 +1,5 @@ from flask import render_template, flash, redirect, request, url_for +from urllib.parse import urlparse from werkzeug.urls import url_parse from app import app from app.forms import * @@ -24,7 +25,11 @@ def login(): return redirect(url_for('login')) login_user(user, remember=form.remember_me.data) next_page=request.args.get('next') - if not next_page or url_parse(next_page).netloc!='': + if next_page: + parsed = urlparse(next_page) + if parsed.netloc or parsed.scheme or not next_page.startswith('/'): + next_page = None + if not next_page: next_page=url_for('index') return redirect(next_page) return render_template('login.html', title='Sign In', form=form) @@ -230,7 +235,12 @@ def cancelbooking(): form=CancelbookingForm() if form.validate_on_submit(): - meeting=Meeting.query.filter_by(id=form.ids.data).first() + meeting=Meeting.query.filter_by( + id=form.ids.data, bookerId=current_user.id + ).first() + if meeting is None: + flash('Meeting not found or you are not authorized to cancel it') + return redirect(url_for('cancelbooking')) if meeting.date<=datetime.now(): flash(f'Past booking cannot be canceled') diff --git a/config.py b/config.py index c9802e0..6cd976f 100644 --- a/config.py +++ b/config.py @@ -1,7 +1,12 @@ import os basedir = os.path.abspath(os.path.dirname(__file__)) class Config(object): - SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess' + SECRET_KEY = os.environ.get('SECRET_KEY') + if not SECRET_KEY: + raise RuntimeError( + "SECRET_KEY environment variable must be set. " + "Generate one with: python -c 'import secrets; print(secrets.token_hex(32))'" + ) SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \ 'sqlite:///' + os.path.join(basedir, 'lab2.db') SQLALCHEMY_TRACK_MODIFICATIONS = False \ No newline at end of file