Security Notes

Security considerations for WPZylos Scaffold plugins.

Generated Code Security

The scaffold generates secure patterns by default:

  • Nonce verification in forms
  • Capability checks in controllers
  • Prepared statements in database queries
  • Output escaping in views
  • Input sanitization before processing

Always review generated code before production.

Security Patterns

Nonce Verification

All form submissions should verify nonces:

// In controller
if (!$this->nonce->verify($_POST['_nonce'] ?? '', 'action_name')) {
    wp_die(__('Invalid request', $this->context->textDomain()));
}
// In view
<input type="hidden" name="_nonce" value="<?php echo esc_attr($nonce); ?>">

Capability Checks

Always check user capabilities:

if (!$this->gate->can('manage_options')) {
    wp_die(__('Unauthorized', $this->context->textDomain()));
}

Input Sanitization

Sanitize all input before processing:

$title = $this->sanitizer->text($_POST['title']);
$content = $this->sanitizer->textarea($_POST['content']);
$email = sanitize_email($_POST['email']);
$id = absint($_POST['id']);

Output Escaping

Always escape output:

<?php echo esc_html($title); ?>
<?php echo esc_attr($value); ?>
<?php echo esc_url($link); ?>
<?php echo wp_kses_post($content); ?>

Or use helpers:

<?php echo zylos_e($title); ?>
<?php echo zylos_ea($value); ?>
<?php echo zylos_eu($link); ?>
<?php echo zylos_kses($content); ?>

Database Queries

Always use prepared statements:

$results = $this->db->getResults(
    $this->db->prepare(
        "SELECT * FROM {$this->table} WHERE user_id = %d AND status = %s",
        $userId,
        $status
    )
);

Activation Security

The scaffold implements lightweight activation without full application boot:

register_activation_hook(__FILE__, function () use ($context) {
    // Only run essential setup
    // Check requirements
    // Register rewrite rules
    // Set default options
    // NO full container boot
});

This prevents potential security issues from running complex code during activation.

PHP-Scoper Security

PHP-Scoper helps prevent:

  • Namespace conflicts between plugins
  • Version conflicts in shared dependencies
  • Supply chain issues by isolating vendor code

The scaffold excludes WordPress core from scoping to maintain compatibility:

'exclude-functions' => [
    'wp_verify_nonce', 'current_user_can', 'sanitize_text_field',
    // ... all WordPress security functions
],

Uninstall Security

The uninstall handler (uninstall.php) includes safety checks:

// Only run from WordPress uninstall
defined('WP_UNINSTALL_PLUGIN') || exit;

// Respect user preference
$keepData = get_option($context->optionKey('keep_data_on_uninstall'), true);
if (!$keepData) {
    Uninstaller::uninstall($context);
}

Security Checklist

Before releasing your plugin:

  • All forms have nonce verification
  • All actions check user capabilities
  • All database queries use prepared statements
  • All output is properly escaped
  • All input is sanitized
  • No direct file access (ABSPATH check)
  • No sensitive data in debug logs
  • Plugin works with WP_DEBUG disabled