mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-05 06:45:09 +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:
@@ -0,0 +1,56 @@
|
||||
"""DELETE /fonts/<name> must refuse every font the repository ships.
|
||||
|
||||
The api's SYSTEM_FONTS was a hand-written list that had drifted from
|
||||
backup_manager.BUNDLED_FONTS: MatrixChunky8X, MatrixLight6X, MatrixLight8X and
|
||||
ic8x8u were missing, so deleting them removed git-tracked files (and the next
|
||||
`git pull` either restored them or conflicted).
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from src.backup_manager import BUNDLED_FONTS # noqa: E402
|
||||
from test._api_v3_test_helpers import api_v3_client, api_v3_module # noqa: F401,E402
|
||||
from web_interface.blueprints.api_v3 import SYSTEM_FONTS # noqa: E402
|
||||
|
||||
SHIPPED_FONT_FILES = sorted(
|
||||
name for name in BUNDLED_FONTS if name.lower().endswith(('.ttf', '.otf', '.bdf')))
|
||||
|
||||
|
||||
def test_every_bundled_font_is_a_system_font():
|
||||
stems = {os.path.splitext(name)[0].lower() for name in SHIPPED_FONT_FILES}
|
||||
assert stems <= SYSTEM_FONTS, stems - SYSTEM_FONTS
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fonts_root(tmp_path):
|
||||
fonts = tmp_path / "assets" / "fonts"
|
||||
fonts.mkdir(parents=True)
|
||||
with patch("web_interface.blueprints.api_v3.fonts.PROJECT_ROOT", tmp_path):
|
||||
yield fonts
|
||||
|
||||
|
||||
@pytest.mark.parametrize("filename", ["MatrixChunky8X.bdf", "MatrixLight6X.bdf",
|
||||
"MatrixLight8X.bdf", "ic8x8u.bdf"])
|
||||
def test_the_previously_unprotected_fonts_cannot_be_deleted(api_v3_client, fonts_root, filename):
|
||||
(fonts_root / filename).write_text("BUNDLED")
|
||||
|
||||
response = api_v3_client.delete(f"/api/v3/fonts/{Path(filename).stem}")
|
||||
|
||||
assert response.status_code == 403
|
||||
assert (fonts_root / filename).exists()
|
||||
|
||||
|
||||
def test_a_user_font_can_still_be_deleted(api_v3_client, fonts_root):
|
||||
(fonts_root / "my-upload.ttf").write_bytes(b"USER")
|
||||
|
||||
response = api_v3_client.delete("/api/v3/fonts/my-upload")
|
||||
|
||||
assert response.status_code == 200, response.get_json()
|
||||
assert not (fonts_root / "my-upload.ttf").exists()
|
||||
Reference in New Issue
Block a user