Fix security issues.
This commit is contained in:
@@ -14,6 +14,7 @@ from flask import (Blueprint, Response, abort, flash, g, redirect, request,
|
||||
from frontmatter_utils import parse_frontmatter
|
||||
from models import Note, db
|
||||
from routes.auth import company_required, login_required
|
||||
from security_utils import sanitize_folder_path, validate_folder_access
|
||||
|
||||
# Create blueprint
|
||||
notes_download_bp = Blueprint('notes_download', __name__)
|
||||
@@ -30,8 +31,11 @@ def download_note(slug, format):
|
||||
if not note.can_user_view(g.user):
|
||||
abort(403)
|
||||
|
||||
# Prepare filename
|
||||
# Prepare filename - extra sanitization
|
||||
safe_filename = re.sub(r'[^a-zA-Z0-9_-]', '_', note.title)
|
||||
# Ensure filename isn't too long
|
||||
if len(safe_filename) > 100:
|
||||
safe_filename = safe_filename[:100]
|
||||
timestamp = datetime.now().strftime('%Y%m%d')
|
||||
|
||||
if format == 'md':
|
||||
@@ -142,6 +146,8 @@ def download_notes_bulk():
|
||||
if note and note.can_user_view(g.user):
|
||||
# Get content based on format
|
||||
safe_filename = re.sub(r'[^a-zA-Z0-9_-]', '_', note.title)
|
||||
if len(safe_filename) > 100:
|
||||
safe_filename = safe_filename[:100]
|
||||
|
||||
if format == 'md':
|
||||
content = note.content
|
||||
@@ -195,8 +201,15 @@ def download_notes_bulk():
|
||||
@company_required
|
||||
def download_folder(folder_path, format):
|
||||
"""Download all notes in a folder as a zip file"""
|
||||
# Decode folder path (replace URL encoding)
|
||||
folder_path = unquote(folder_path)
|
||||
# Decode and sanitize folder path
|
||||
try:
|
||||
folder_path = sanitize_folder_path(unquote(folder_path))
|
||||
except ValueError:
|
||||
abort(400, "Invalid folder path")
|
||||
|
||||
# Validate folder exists and user has access
|
||||
if not validate_folder_access(folder_path, g.user.company_id, db.session):
|
||||
abort(404, "Folder not found")
|
||||
|
||||
# Get all notes in this folder
|
||||
notes = Note.query.filter_by(
|
||||
@@ -220,6 +233,8 @@ def download_folder(folder_path, format):
|
||||
for note in viewable_notes:
|
||||
# Get content based on format
|
||||
safe_filename = re.sub(r'[^a-zA-Z0-9_-]', '_', note.title)
|
||||
if len(safe_filename) > 100:
|
||||
safe_filename = safe_filename[:100]
|
||||
|
||||
if format == 'md':
|
||||
content = note.content
|
||||
|
||||
Reference in New Issue
Block a user