mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-13 05:53:00 +00:00
feat(starlark): schema-driven config forms + critical security fixes
## Schema-Driven Config UI - Render type-appropriate form inputs from schema.json (text, dropdown, toggle, color, datetime, location) - Pre-populate config.json with schema defaults on install - Auto-merge schema defaults when loading existing apps (handles schema updates) - Location fields: 3-part mini-form (lat/lng/timezone) assembles into JSON - Toggle fields: support both boolean and string "true"/"false" values - Unsupported field types (oauth2, photo_select) show warning banners - Fallback to raw key/value inputs for apps without schema ## Critical Security Fixes (P0) - **Path Traversal**: Verify path safety BEFORE mkdir to prevent TOCTOU - **Race Conditions**: Add file locking (fcntl) + atomic writes to manifest operations - **Command Injection**: Validate config keys/values with regex before passing to Pixlet subprocess ## Major Logic Fixes (P1) - **Config/Manifest Separation**: Store timing keys (render_interval, display_duration) ONLY in manifest - **Location Validation**: Validate lat [-90,90] and lng [-180,180] ranges, reject malformed JSON - **Schema Defaults Merge**: Auto-apply new schema defaults to existing app configs on load - **Config Key Validation**: Enforce alphanumeric+underscore format, prevent prototype pollution ## Files Changed - web_interface/templates/v3/partials/starlark_config.html — schema-driven form rendering - plugin-repos/starlark-apps/manager.py — file locking, path safety, config validation, schema merge - plugin-repos/starlark-apps/pixlet_renderer.py — config value sanitization - web_interface/blueprints/api_v3.py — timing key separation, safe manifest updates Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import json
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
@@ -250,11 +251,23 @@ class PixletRenderer:
|
||||
# Add configuration parameters
|
||||
if config:
|
||||
for key, value in config.items():
|
||||
# Validate key format (alphanumeric + underscore only)
|
||||
if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', key):
|
||||
logger.warning(f"Skipping invalid config key: {key}")
|
||||
continue
|
||||
|
||||
# Convert value to string for CLI
|
||||
if isinstance(value, bool):
|
||||
value_str = "true" if value else "false"
|
||||
else:
|
||||
value_str = str(value)
|
||||
|
||||
# Validate value doesn't contain shell metacharacters
|
||||
# Allow alphanumeric, spaces, and common safe chars: .-_:/@#,
|
||||
if not re.match(r'^[a-zA-Z0-9 .\-_:/@#,{}"\[\]]*$', value_str):
|
||||
logger.warning(f"Skipping config value with unsafe characters for key {key}: {value_str}")
|
||||
continue
|
||||
|
||||
cmd.extend(["-c", f"{key}={value_str}"])
|
||||
|
||||
logger.debug(f"Executing Pixlet: {' '.join(cmd)}")
|
||||
|
||||
Reference in New Issue
Block a user