Admin Interface CSP Configuration
Admin Interface CSP Configuration
Providing a user-friendly interface for CSP management helps site administrators maintain security without technical expertise.
// Admin interface for CSP management
class WP_CSP_Admin {
public function __construct() {
add_action('admin_menu', [$this, 'add_admin_menu']);
add_action('admin_init', [$this, 'register_settings']);
add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']);
}
public function add_admin_menu() {
add_menu_page(
'CSP Settings',
'CSP Security',
'manage_options',
'wp-csp-settings',
[$this, 'settings_page'],
'dashicons-shield',
30
);
add_submenu_page(
'wp-csp-settings',
'CSP Violations',
'Violations Log',
'manage_options',
'wp-csp-violations',
[$this, 'violations_page']
);
}
public function settings_page() {
?>
<div class="wrap">
<h1>Content Security Policy Settings</h1>
<div class="csp-status-widget">
<h2>Current Status</h2>
<?php $this->display_csp_status(); ?>
</div>
<form method="post" action="options.php">
<?php settings_fields('wp_csp_settings'); ?>
<h2>Policy Configuration</h2>
<table class="form-table">
<tr>
<th scope="row">Implementation Mode</th>
<td>
<select name="csp_mode">
<option value="report-only">Report Only (Testing)</option>
<option value="enforce">Enforce (Production)</option>
</select>
</td>
</tr>
<tr>
<th scope="row">Allowed Script Sources</th>
<td>
<textarea name="csp_script_sources" rows="5" cols="60"><?php
echo esc_textarea(get_option('csp_script_sources'));
?></textarea>
<p class="description">One source per line (e.g., https://example.com)</p>
</td>
</tr>
<tr>
<th scope="row">Allowed Style Sources</th>
<td>
<textarea name="csp_style_sources" rows="5" cols="60"><?php
echo esc_textarea(get_option('csp_style_sources'));
?></textarea>
</td>
</tr>
</table>
<h2>Plugin Compatibility</h2>
<?php $this->display_plugin_compatibility(); ?>
<?php submit_button(); ?>
</form>
</div>
<?php
}
private function display_csp_status() {
global $wpdb;
$table_name = $wpdb->prefix . 'csp_violations';
$violations_24h = $wpdb->get_var(
"SELECT COUNT(*) FROM $table_name
WHERE timestamp > DATE_SUB(NOW(), INTERVAL 24 HOUR)"
);
$mode = get_option('csp_mode', 'report-only');
$status_class = $mode === 'enforce' ? 'active' : 'testing';
?>
<div class="csp-status <?php echo $status_class; ?>">
<p><strong>Mode:</strong> <?php echo ucfirst($mode); ?></p>
<p><strong>Violations (24h):</strong> <?php echo $violations_24h; ?></p>
<p><strong>Last Updated:</strong> <?php echo get_option('csp_last_updated', 'Never'); ?></p>
</div>
<?php
}
private function display_plugin_compatibility() {
$active_plugins = get_option('active_plugins');
$compatible_plugins = $this->get_compatible_plugins();
echo '<table class="wp-list-table widefat fixed striped">';
echo '<thead><tr><th>Plugin</th><th>Compatibility</th><th>Required CSP Changes</th></tr></thead>';
echo '<tbody>';
foreach ($active_plugins as $plugin) {
$plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
$plugin_name = $plugin_data['Name'];
$plugin_slug = dirname($plugin);
$compatibility = isset($compatible_plugins[$plugin_slug]) ?
'Compatible' : 'May require configuration';
echo '<tr>';
echo '<td>' . esc_html($plugin_name) . '</td>';
echo '<td>' . esc_html($compatibility) . '</td>';
echo '<td>';
if (isset($compatible_plugins[$plugin_slug])) {
foreach ($compatible_plugins[$plugin_slug] as $directive => $sources) {
echo esc_html($directive) . ': ' . implode(', ', $sources) . '<br>';
}
}
echo '</td>';
echo '</tr>';
}
echo '</tbody></table>';
}
}