Security Notes
Security considerations for wpzylos-core.
PluginContext Security
Prefix Isolation
Context prefixes isolate plugin resources. Always use context methods for:
// Options
$key = $context->optionKey('settings'); // myplugin_settings
// Transients
$key = $context->transientKey('cache'); // myplugin_cache
// Custom hooks
$hook = $context->hook('data_saved'); // myplugin_data_saved
// Database tables
$table = $context->tableName('orders'); // wp_myplugin_orders
Never Expose Context Internals
Don't expose prefix or internal paths to users:
// Bad: Exposes internal structure
echo "Table: " . $context->tableName('users');
// Good: Use prefixed data, hide structure
$users = $repository->all();
Service Provider Security
Validate External Input in Boot
Providers may interact with user data during boot. Validate:
public function boot(): void
{
$hooks = $this->app->container()->get(HookManager::class);
$hooks->wpAction('init', function () {
// Validate before using
$page = sanitize_text_field($_GET['page'] ?? '');
if ($page === $this->context->slug()) {
// Safe to proceed
}
});
}
Don't Trust Configuration Blindly
If config comes from database or user input:
$providers = get_option($context->optionKey('custom_providers'), []);
// Validate before instantiating
foreach ($providers as $class) {
if (class_exists($class) && is_subclass_of($class, ServiceProvider::class)) {
$app->register(new $class());
}
}
Path Security
Validate Relative Paths
When accepting user-provided paths:
// Bad: Dangerous: path traversal
$file = $context->path($_GET['template']);
// Good: Safe: validate and restrict
$template = basename($_GET['template'] ?? 'default');
$allowed = ['default', 'custom', 'minimal'];
if (in_array($template, $allowed, true)) {
$file = $context->path('templates/' . $template . '.php');
}
Related
- Security Package — Full security utilities
- Validation Package — Input validation