mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 14:25:08 +00:00
fix(security): refuse unsafe plugin ids, keep secrets private, validate request bodies (#643)
* fix(security): refuse unsafe plugin ids, keep secrets private, validate bodies - install_from_url and the registry install's manifest rename refuse a plugin id that is not a single safe name (no ../ out of plugins_dir). - Uninstall and config reset refuse core config sections and ids with path parts; uninstall of a plugin whose directory is gone still works. - separate_secrets checks a field's own x-secret marker before recursing, so object/array secrets no longer land in config.json. - Backup restore creates missing secrets/wifi/ytm files with mode 640; export skips non-object manifests and no longer collides on same-second exports. - SYSTEM_FONTS includes every bundled font from BUNDLED_FONTS. - Raw config/secrets saves and validate_request_json require a JSON object. - A blank max_dynamic_duration_seconds keeps the stored value; other values are validated to 30-1800 instead of raising a 500. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(security): validate the id before install_plugin moves anything; claim backup names atomically - install_plugin set aside plugins_dir / plugin_id before any id check, so "../x" moved a directory outside the plugins dir (the rollback moved it back, but only if the install path got that far) - two exports finishing in the same second could both see a free name and the later os.replace destroyed the first archive; the name is now claimed with O_EXCL before the archive is swapped in Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ so their endpoint names are unchanged by living here.
|
||||
from web_interface.blueprints.api_v3 import (
|
||||
ErrorCode, OperationType, PROJECT_ROOT, Path, Response,
|
||||
_CALENDAR_LIST_MAX_PAGES, _RENDERED_SECTION_FIELD, _SKIP_FIELD, _coerce_to_bool,
|
||||
_do_transactional_uninstall, _enhance_schema_with_core_properties,
|
||||
_do_transactional_uninstall, _enhance_schema_with_core_properties, _non_plugin_id_error,
|
||||
_filter_config_by_schema, _get_plugin_version, _get_schema_property,
|
||||
_hidden_array_item_property, _installed_plugin_ids, _is_plugin_update_available,
|
||||
_plugin_directory,
|
||||
@@ -1107,6 +1107,9 @@ def uninstall_plugin():
|
||||
|
||||
plugin_id = data['plugin_id']
|
||||
preserve_config = data.get('preserve_config', False)
|
||||
id_error = _non_plugin_id_error(plugin_id)
|
||||
if id_error:
|
||||
return id_error
|
||||
|
||||
# Both queued and direct paths use the same transactional helper so
|
||||
# snapshot/rollback behaviour is consistent regardless of deployment.
|
||||
@@ -2338,6 +2341,9 @@ def reset_plugin_config():
|
||||
|
||||
if not plugin_id:
|
||||
return jsonify({'status': 'error', 'message': 'plugin_id required'}), 400
|
||||
id_error = _non_plugin_id_error(plugin_id)
|
||||
if id_error:
|
||||
return id_error
|
||||
|
||||
# Get schema manager instance
|
||||
schema_mgr = api_v3.schema_manager
|
||||
|
||||
Reference in New Issue
Block a user