Security

Overview

WPZylos Notification handles sensitive data (email addresses, user IDs, notification content) and renders HTML output. This page covers security considerations and best practices.

Output Escaping

MailMessage

The MailMessage::render() method escapes all output:

  • Greeting — Escaped via esc_html()
  • Body lines — Escaped via esc_html()
  • Action URL — Escaped via esc_url()
  • Action text — Escaped via esc_html()

AdminNoticeMessage

The AdminNoticeMessage::render() method uses:

  • Type — Escaped via esc_attr()
  • Message — Filtered via wp_kses_post() (allows safe HTML)

Important: If you pass user-generated content to AdminNoticeMessage::message(), ensure you sanitize it first, as wp_kses_post() allows certain HTML tags.

Data Sanitization

Database Channel

Data stored in the database channel is serialized via wp_json_encode(). Always validate and sanitize notification data in your toDatabase() method:

public function toDatabase(object $notifiable): array
{
    return [
        'order_id' => absint($this->order->id),
        'message'  => sanitize_text_field($this->message),
    ];
}

Email Addresses

The MailChannel resolves email addresses via routeNotificationFor('mail'). Validate email addresses in your notifiable's routing:

public function routeNotificationFor(string $channel): mixed
{
    if ($channel === 'mail') {
        return is_email($this->email) ? $this->email : null;
    }
    // ...
}

SQL Injection Prevention

  • The DatabaseChannel uses the WPZylos Connection query builder with parameterized queries
  • The DatabaseNotificationInstaller uses dbDelta() for safe schema creation
  • The Notifiable trait uses query builder methods for reads and parameterized raw queries for complex filters

Transient Security

The AdminNoticeChannel stores notices in WordPress transients with:

  • User-scoped keys — Each user's notices are stored under a unique, prefixed transient key
  • Expiration — Notices expire after HOUR_IN_SECONDS (1 hour)
  • One-time display — Notices are deleted after being rendered

Authorization

The notification system does not enforce authorization. Ensure you verify that the sender has permission to notify the target:

// Check capability before sending admin notifications
if (current_user_can('manage_options')) {
    $admin->notify(new SystemAlert($error));
}

Reporting Vulnerabilities

See security.md for vulnerability reporting instructions.