Fix path injection and stack trace exposure vulnerabilities

Co-authored-by: aiulian25 <17886483+aiulian25@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-11-12 21:48:44 +00:00
parent 90143f7dc0
commit 6402a8480d

View file

@ -405,14 +405,23 @@ def download_attachment():
if not file_path: if not file_path:
return jsonify({'error': 'No file path provided'}), 400 return jsonify({'error': 'No file path provided'}), 400
full_path = os.path.join('/app/uploads', file_path) # Normalize the file path to prevent directory traversal
file_path = os.path.normpath(file_path)
if not os.path.exists(full_path): # Ensure the path doesn't try to escape the uploads directory
return jsonify({'error': 'File not found'}), 404 if '..' in file_path or file_path.startswith('/'):
if not full_path.startswith('/app/uploads'):
return jsonify({'error': 'Invalid file path'}), 403 return jsonify({'error': 'Invalid file path'}), 403
full_path = os.path.normpath(os.path.join('/app/uploads', file_path))
# Double-check the resolved path is within the uploads directory
if not full_path.startswith('/app/uploads/'):
return jsonify({'error': 'Invalid file path'}), 403
# Check if the file exists and is actually a file (not a directory)
if not os.path.isfile(full_path):
return jsonify({'error': 'File not found'}), 404
directory = os.path.dirname(full_path) directory = os.path.dirname(full_path)
filename = os.path.basename(full_path) filename = os.path.basename(full_path)
@ -427,19 +436,29 @@ def delete_attachment():
if not file_path: if not file_path:
return jsonify({'error': 'No file path provided'}), 400 return jsonify({'error': 'No file path provided'}), 400
full_path = os.path.join('/app/uploads', file_path) # Normalize the file path to prevent directory traversal
file_path = os.path.normpath(file_path)
if not full_path.startswith('/app/uploads'): # Ensure the path doesn't try to escape the uploads directory
if '..' in file_path or file_path.startswith('/'):
return jsonify({'error': 'Invalid file path'}), 403 return jsonify({'error': 'Invalid file path'}), 403
if not os.path.exists(full_path): full_path = os.path.normpath(os.path.join('/app/uploads', file_path))
# Double-check the resolved path is within the uploads directory
if not full_path.startswith('/app/uploads/'):
return jsonify({'error': 'Invalid file path'}), 403
# Check existence without revealing path details
if not os.path.isfile(full_path):
return jsonify({'error': 'File not found'}), 404 return jsonify({'error': 'File not found'}), 404
try: try:
os.remove(full_path) os.remove(full_path)
return jsonify({'message': 'Attachment deleted successfully'}), 200 return jsonify({'message': 'Attachment deleted successfully'}), 200
except Exception as e: except OSError:
return jsonify({'error': f'Failed to delete attachment: {str(e)}'}), 500 # Don't expose internal error details
return jsonify({'error': 'Failed to delete attachment'}), 500
@app.route('/api/vehicles/<int:vehicle_id>', methods=['GET', 'PUT', 'DELETE']) @app.route('/api/vehicles/<int:vehicle_id>', methods=['GET', 'PUT', 'DELETE'])
@login_required @login_required