mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-05-15 10:03:31 +00:00
fix(security): escape user input in raw HTML responses in pages_v3.py
plugin_id comes directly from the URL path (/partials/plugin-config/<plugin_id>) and was interpolated into an HTML fragment without escaping. A crafted URL like /partials/plugin-config/<script>alert(1)</script> would inject that tag into the DOM via the HTMX partial response. Fix: wrap all user-controlled values in markupsafe.escape() before embedding in raw HTML strings. Affects the plugin-not-found 404 response and both error 500 responses in the plugin config partial. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
from flask import Blueprint, render_template, flash
|
from flask import Blueprint, render_template, flash
|
||||||
|
from markupsafe import escape
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -95,7 +96,7 @@ def load_plugin_config_partial(plugin_id):
|
|||||||
try:
|
try:
|
||||||
return _load_plugin_config_partial(plugin_id)
|
return _load_plugin_config_partial(plugin_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f'<div class="text-red-500 p-4">Error loading plugin config: {str(e)}</div>', 500
|
return f'<div class="text-red-500 p-4">Error loading plugin config: {escape(str(e))}</div>', 500
|
||||||
|
|
||||||
def _load_overview_partial():
|
def _load_overview_partial():
|
||||||
"""Load overview partial with system stats"""
|
"""Load overview partial with system stats"""
|
||||||
@@ -352,7 +353,7 @@ def _load_plugin_config_partial(plugin_id):
|
|||||||
plugin_info = pages_v3.plugin_manager.get_plugin_info(plugin_id)
|
plugin_info = pages_v3.plugin_manager.get_plugin_info(plugin_id)
|
||||||
|
|
||||||
if not plugin_info:
|
if not plugin_info:
|
||||||
return f'<div class="text-red-500 p-4">Plugin "{plugin_id}" not found</div>', 404
|
return f'<div class="text-red-500 p-4">Plugin "{escape(plugin_id)}" not found</div>', 404
|
||||||
|
|
||||||
# Get plugin instance (may be None if not loaded)
|
# Get plugin instance (may be None if not loaded)
|
||||||
plugin_instance = pages_v3.plugin_manager.get_plugin(plugin_id)
|
plugin_instance = pages_v3.plugin_manager.get_plugin(plugin_id)
|
||||||
@@ -454,7 +455,7 @@ def _load_plugin_config_partial(plugin_id):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return f'<div class="text-red-500 p-4">Error loading plugin config: {str(e)}</div>', 500
|
return f'<div class="text-red-500 p-4">Error loading plugin config: {escape(str(e))}</div>', 500
|
||||||
|
|
||||||
|
|
||||||
def _load_starlark_config_partial(app_id):
|
def _load_starlark_config_partial(app_id):
|
||||||
|
|||||||
Reference in New Issue
Block a user