Skip to content

Security

Asterios Raptis edited this page May 19, 2026 · 2 revisions

Security

PluginForge includes security measures to prevent path traversal attacks and validate plugin names.

Plugin Name Validation

Plugin names are used to construct file paths (config/plugins/{name}.yaml). A malicious plugin name like ../../etc/passwd could read arbitrary files. PluginForge prevents this by validating all plugin names.

Rules

  • Must start with a letter
  • May contain letters, digits, underscores, or hyphens
  • Maximum 64 characters
  • No path separators (/, \), dots (.), or spaces

When Validation Happens

Plugin names are validated automatically in:

  • load_plugin_config() - before loading plugin YAML
  • load_i18n() - before loading language YAML
  • register_plugin() - before registering a plugin instance
  • _activate_with_states() - during discovery/registration pipelines (renamed from _activate_ordered in v0.6.0)

InvalidPluginNameError

Invalid names raise InvalidPluginNameError (a subclass of ValueError):

from pluginforge import InvalidPluginNameError

try:
    pm.register_plugin(evil_plugin)
except InvalidPluginNameError as e:
    print(f"Rejected: {e}")

Path Traversal Prevention

Config Loading

The load_plugin_config() and load_i18n() functions validate their name parameters before constructing file paths. This prevents directory traversal via plugin names or language codes.

Alembic Migrations

Migration directories returned by get_migrations_dir() are resolved to absolute paths. Symlink chains are followed to their real location before being accepted.

Utility Functions

validate_plugin_name(name: str) -> None

Validate a plugin name. Raises InvalidPluginNameError if invalid.

from pluginforge.security import validate_plugin_name

validate_plugin_name("my-plugin")      # ok
validate_plugin_name("../etc/passwd")  # raises InvalidPluginNameError

validate_safe_path(path: str, allowed_base: str) -> bool

Check that a resolved path stays within an allowed base directory.

from pluginforge.security import validate_safe_path

validate_safe_path("/app/config/plugins/export.yaml", "/app/config")  # True
validate_safe_path("/app/config/../../etc/passwd", "/app/config")     # False

Best Practices

  • Always use PluginManager methods to load configs rather than constructing paths manually
  • If accepting plugin names from user input (e.g. a settings UI), the validation is automatic
  • For custom file operations with plugin-derived paths, use validate_safe_path() to check containment

Clone this wiki locally