Security functions implement best practices for protecting your WordPress site from common vulnerabilities and attacks.
Sets HTTP security headers to prevent various types of attacks including XSS, clickjacking, and MIME-type sniffing.
Location: inc/security.php:13
This function does not return a value. It sets HTTP headers in the response.
Headers Set:
-
X-Content-Type-Options: nosniff
- Prevents MIME-type sniffing attacks
- Tells browsers to respect the Content-Type header
- Blocks execution of scripts with incorrect MIME types
-
X-Frame-Options: SAMEORIGIN
- Prevents clickjacking attacks
- Allows framing only from same origin
- Protects against UI redress attacks
-
X-XSS-Protection: 1; mode=block
- Enables browser XSS filtering
- Blocks page rendering if XSS attack detected
- Additional layer of protection for older browsers
Hook: Automatically added to send_headers action
// Headers are automatically sent on every page load
add_action('send_headers', 'vertisub_security_headers');
Response Headers:
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Security Best Practices
The theme implements several security measures throughout:
Nonce Verification
All form submissions use WordPress nonces for CSRF protection:
// Example from contact form handler
if (!wp_verify_nonce($_POST['nonce'], 'sancho_nonce')) {
wp_die('Security check failed');
}
All user input is sanitized before processing:
// Text field sanitization
$name = sanitize_text_field($_POST['name']);
// Email sanitization
$email = sanitize_email($_POST['email']);
// Textarea sanitization
$message = sanitize_textarea_field($_POST['message']);
// URL sanitization
$url = esc_url_raw($_POST['url']);
// HTML content sanitization (allows safe HTML)
$content = wp_kses_post($_POST['content']);
Capability Checks
User permissions are verified before data modifications:
// Check if user can edit post
if (!current_user_can('edit_post', $post_id)) {
return;
}
Autosave Prevention
Meta box saves are protected from autosave interference:
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
Additional Security Recommendations
While the theme implements several security measures, consider these additional protections:
Content Security Policy (CSP)
Add a more comprehensive CSP header:
function my_enhanced_security_headers() {
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';");
}
add_action('send_headers', 'my_enhanced_security_headers');
Strict Transport Security (HSTS)
Force HTTPS connections:
function my_hsts_header() {
if (is_ssl()) {
header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
}
}
add_action('send_headers', 'my_hsts_header');
Referrer Policy
Control referrer information:
function my_referrer_policy() {
header('Referrer-Policy: strict-origin-when-cross-origin');
}
add_action('send_headers', 'my_referrer_policy');
Permissions Policy
Control browser features:
function my_permissions_policy() {
header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
}
add_action('send_headers', 'my_permissions_policy');
Security Testing
Test your security headers using online tools:
// Verify headers are being sent
function check_security_headers() {
if (WP_DEBUG) {
$headers = headers_list();
error_log('Current headers: ' . print_r($headers, true));
}
}
add_action('wp_head', 'check_security_headers');
Common Security Patterns
Escaping Output
Always escape data when outputting to HTML:
// Text content
echo esc_html($text);
// HTML attributes
echo '<div class="' . esc_attr($class) . '">';
// URLs
echo '<a href="' . esc_url($url) . '">';
// JavaScript
echo '<script>var data = ' . wp_json_encode($data) . ';</script>';
// Textarea content
echo '<textarea>' . esc_textarea($content) . '</textarea>';
Validating File Uploads
function validate_file_upload($file) {
$allowed_types = array('image/jpeg', 'image/png', 'application/pdf');
if (!in_array($file['type'], $allowed_types)) {
return new WP_Error('invalid_type', 'Invalid file type');
}
if ($file['size'] > 5242880) { // 5MB
return new WP_Error('too_large', 'File too large');
}
return true;
}
Protecting AJAX Endpoints
function my_ajax_handler() {
// Verify nonce
check_ajax_referer('my_nonce', 'nonce');
// Check capabilities
if (!current_user_can('edit_posts')) {
wp_send_json_error('Insufficient permissions');
}
// Sanitize input
$data = sanitize_text_field($_POST['data']);
// Process and respond
wp_send_json_success($data);
}
add_action('wp_ajax_my_action', 'my_ajax_handler');