Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Critical sandbox bypasses permit OS-command execution without opt-in, while Python 3.5 incompatibility breaks script loading and missing prerequisite scripts block clean-checkout image builds.
4 open issues
What changed in this PR
This PR adds restricted loading for user-supplied Python filter scripts in Fledge, aiming to reduce access to OS commands and interpreter internals.
Changes:
- Adds AST validation, restricted builtins, and import allow-lists during configuration and reconfiguration.
- Updates error logging, examples, documentation, and sandbox regression tests.
- Adds Docker-based build, test, and development runtime tooling.
| File | Description |
|---|---|
tests/test_python35.cpp |
Adds rejection and allowed-script regression tests. |
README.rst |
Documents script restrictions and operator-controlled imports. |
readings35.py |
Removes the unused sys import. |
python35_filter.cpp |
Integrates restricted loading and safer error logging. |
include/script_sandbox.h |
Defines source validation and restricted execution. |
include/python35.h |
Declares the loader and its stored Python reference. |
examples/scale35.py |
Replaces restricted imports and syslog logging with stdout diagnostics. |
docker-compose.yml |
Defines development runtime and test services. |
.dockerignore |
Excludes host build output from Docker contexts. |
.ci/deb/test.sh |
Adds a Docker test-build wrapper. |
.ci/deb/Dockerfile |
Adds build, test, runtime, and artifact stages. |
.ci/compose/entrypoint.sh |
Starts syslog and Fledge, then streams logs. |
Review effort: Balanced
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Restrict imports in user-supplied filter scripts (PT-HLN-HDP-26A-002, CWE-78)
Problem
Filter scripts were loaded with
PyImport_ImportModule/PyImport_ReloadModule, sothey ran with no restrictions. Anyone who can edit a script (including via the
Configurator) could
import os,subprocess,socket,ctypesetc. and runarbitrary OS commands as the Fledge service user.
Changes
include/script_sandbox.h: embedded Python loader (load_script) thatreads the script source instead of importing it, then
an allow-list, relative/star imports, dunder attribute access
(
__class__,__subclasses__, ...),__import__/__builtins__, andeval,exec,compile,open,getattrand similar builtins;__builtins__and an__import__that enforces the same allow-list at run time.python35_filter.cpp/python35.h: newPython35Filter::loadScript(),used in
configure()and both paths ofreconfigure()so scripts are checked onstart and on every reconfigure. Script names containing
/or..are rejected.The loader is released in
shutdown().logErrorMessage()rewritten withstd::stringand null-safehelpers. Sandbox rejections are logged with the reason and line number. This also
removes the old unchecked
PyBytes_AsString/rindexhandling.readings are dropped.
json math cmath time datetime re copy collections itertools functools string decimal fractions statistics numbers random bisect heapq struct base64 binascii hashlib hmac enum typing textwrap unicodedata.The deny-list (
os subprocess socket sys ctypes importlib shutil io threading multiprocessing pickle urllib http ...) cannot be overridden.FLEDGE_PYTHON35_EXTRA_IMPORTS(comma-separatedexact module names) adds modules. It is read from the service environment, not the
filter config category, because that category is editable by script authors.
examples/scale35.pyandreadings35.pyno longer importos/sys/logging. README gains a "Script restrictions" section.PYTHON35.Sandbox*cases intests/test_python35.cpp..ci/deb/Dockerfile,.ci/deb/test.sh,.ci/compose/,os/sys/logging. README gains a "Script restrictions" section.PYTHON35.Sandbox*cases intests/test_python35.cpp..ci/deb/Dockerfile,.ci/deb/test.sh,.ci/compose/,docker-compose.yml,.dockerignorefor building and running the tests in acontainer.
Breaking change
Existing scripts that import
os,sys,loggingor other non-allow-listedmodules will now be rejected and must be updated, or the module must be added via
FLEDGE_PYTHON35_EXTRA_IMPORTS. The oldexamples/scale35.pywas one such script.Security notes
This is defence in depth, not a complete sandbox. In-process Python restrictions
can be bypassed by a determined author. Fledge should still run with least
privilege, and edit access to filter scripts should be restricted. Any module added
via the env var widens the attack surface (for example,
loggingcan write files).Testing
PYTHON35.Sandbox*unit tests passosis rejected and logged, and the filter drops readings