Skip to content

Commit 4829b37

Browse files
authored
Release
1 parent b211beb commit 4829b37

File tree

4 files changed

+142
-14
lines changed

4 files changed

+142
-14
lines changed

CHANGELOG.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
55

66
## [Unreleased]
77

8+
## [1.5.7] - 2025-06-15
9+
### Added
10+
- WordPress nonce protection for CSRF security in settings forms
11+
- Enhanced DNS prefetch security with HTTPS-only domain enforcement
12+
- Private IP and localhost blocking for DNS prefetch domains to prevent SSRF attacks
13+
- Comprehensive domain validation with multi-layer security checks
14+
- User-friendly error messages for rejected domains with proper HTML escaping
15+
- Security event notifications for administrators when domains are rejected
16+
17+
### Enhanced
18+
- Strengthened form security with wp_nonce_field() and wp_verify_nonce() implementation
19+
- Improved DNS prefetch domain validation with parse_url() and enhanced filtering
20+
- Enhanced error handling with proper WordPress admin notices and escaping
21+
- Updated help text to clearly indicate HTTPS requirement for DNS prefetch domains
22+
- Better user experience with informative security-related error messages
23+
- Comprehensive input validation preventing malicious domain submissions
24+
25+
### Security
26+
- **CSRF Protection**: Added WordPress nonce verification for all form submissions
27+
- **HTTPS Enforcement**: DNS prefetch domains now require HTTPS protocol for security
28+
- **SSRF Prevention**: Blocked private IP ranges and localhost addresses in DNS prefetch
29+
- **Input Validation**: Enhanced multi-layer validation for all user-submitted domains
30+
- **Output Escaping**: Improved HTML escaping for all error messages and user feedback
31+
- **Attack Surface Reduction**: Eliminated potential vectors for security exploitation
32+
33+
### Fixed
34+
- Resolved potential XSS vulnerability in error message display by adding proper HTML escaping
35+
- Fixed domain validation to prevent bypass of security checks
36+
- Improved error message construction to prevent information disclosure
37+
838
## [1.5.6] - 2025-05-31
939
### Added
1040
- Enhanced GitHub Actions workflows for comprehensive plugin testing and security analysis

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![PHP Compatible](https://img.shields.io/badge/PHP-7.4%2B-purple.svg?logo=php)](https://www.php.net/)
77

88
## Current Version
9-
[![Version](https://img.shields.io/badge/Version-1.5.6-orange.svg?logo=github)](https://github.com/EngineScript/Simple-WP-Optimizer/releases/download/v1.5.6/simple-wp-optimizer-1.5.6.zip)
9+
[![Version](https://img.shields.io/badge/Version-1.5.7-orange.svg?logo=github)](https://github.com/EngineScript/Simple-WP-Optimizer/releases/download/v1.5.7/simple-wp-optimizer-1.5.7.zip)
1010

1111
## Description
1212

@@ -17,9 +17,21 @@ A lightweight WordPress plugin designed to optimize your website by removing unn
1717
- **Header Cleanup:** Remove WordPress version, WLW manifest links, and shortlinks
1818
- **Script Optimization:** Disable WordPress emojis and remove jQuery Migrate
1919
- **Style Optimization:** Remove inline styles from recent comments widget and disable classic theme styles
20-
- **DNS Prefetching:** Add DNS prefetch for common external domains to improve load times
20+
- **DNS Prefetching:** Add DNS prefetch for common external domains to improve load times (HTTPS-only for security)
2121
- **Jetpack Optimization:** Remove Jetpack advertisements and promotions
2222

23+
## Security Features
24+
25+
This plugin implements comprehensive security measures following WordPress and OWASP best practices:
26+
27+
- **CSRF Protection:** WordPress nonce verification for all form submissions
28+
- **Input Validation:** Multi-layer validation and sanitization for all user inputs
29+
- **Output Escaping:** Context-appropriate escaping for all outputs (HTML, attributes, URLs)
30+
- **HTTPS Enforcement:** DNS prefetch domains must use HTTPS protocol for security
31+
- **SSRF Prevention:** Blocks private IP ranges and localhost addresses
32+
- **Capability Checks:** Proper user permission verification for all admin functions
33+
- **Direct Access Prevention:** Prevents direct script execution outside WordPress
34+
2335
## Installation
2436

2537
### Manual Installation

readme.txt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Contributors: enginescript
33
Tags: optimization, performance, cleanup
44
Requires at least: 6.0
55
Tested up to: 6.8
6-
Stable tag: 1.5.6
6+
Stable tag: 1.5.7
77
Requires PHP: 7.4
88
License: GPLv2 or later
99
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -42,6 +42,22 @@ No, the plugin has a simple interface where you can toggle features on and off.
4242

4343
== Changelog ==
4444

45+
= 1.5.7 =
46+
* **SECURITY ENHANCEMENT**: Added WordPress nonce protection for CSRF security in all form submissions
47+
* **SECURITY ENHANCEMENT**: Enhanced DNS prefetch security with HTTPS-only domain enforcement
48+
* **SECURITY ENHANCEMENT**: Added private IP and localhost blocking for DNS prefetch to prevent SSRF attacks
49+
* **SECURITY ENHANCEMENT**: Implemented comprehensive domain validation with multi-layer security checks
50+
* Added user-friendly error messages for rejected domains with proper HTML escaping
51+
* Added security event notifications for administrators when domains are rejected for security reasons
52+
* Strengthened form security with proper wp_nonce_field() and wp_verify_nonce() implementation
53+
* Improved DNS prefetch domain validation with enhanced URL parsing and filtering
54+
* Enhanced error handling with proper WordPress admin notices and comprehensive escaping
55+
* Updated help text to clearly indicate HTTPS requirement for DNS prefetch domains
56+
* Fixed potential XSS vulnerability in error message display through proper HTML escaping
57+
* Improved domain validation to prevent bypass of security checks and information disclosure
58+
* Better user experience with informative, security-focused error messages
59+
* Comprehensive input validation preventing malicious domain submissions and attacks
60+
4561
= 1.5.6 =
4662
* Enhanced GitHub Actions workflows for comprehensive plugin testing and security analysis
4763
* Added PHPStan WordPress static analysis with proper WordPress stubs configuration
@@ -80,6 +96,14 @@ No, the plugin has a simple interface where you can toggle features on and off.
8096
* Made the plugin fully compatible with the WordPress Plugin Check tool
8197
* Improved documentation and code comments
8298

99+
== Upgrade Notice ==
100+
101+
= 1.5.7 =
102+
SECURITY UPDATE: This version adds important security enhancements including CSRF protection and enhanced DNS prefetch security. Update recommended for all users.
103+
104+
= 1.5.6 =
105+
Major security and code quality improvements with PHPStan analysis and WordPress best practices compliance.
106+
83107
= 1.5.4 =
84108
* Security enhancements and code optimization
85109

simple-wp-optimizer.php

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Plugin Name: EngineScript: Simple WP Optimization
44
Plugin URI: https://github.com/EngineScript/Simple-WP-Optimizer
55
Description: Optimizes WordPress by removing unnecessary features and scripts to improve performance
6-
Version: 1.5.6
6+
Version: 1.5.7
77
Author: EngineScript
88
License: GPL v2 or later
99
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -51,7 +51,7 @@
5151

5252
// Define plugin version
5353
if (!defined('ES_WP_OPTIMIZER_VERSION')) {
54-
define('ES_WP_OPTIMIZER_VERSION', '1.5.6');
54+
define('ES_WP_OPTIMIZER_VERSION', '1.5.7');
5555
}
5656

5757
/**
@@ -128,7 +128,10 @@ function es_optimizer_settings_page() {
128128
<p>Select which optimizations you want to enable and customize the DNS prefetch domains.</p>
129129

130130
<form method="post" action="options.php">
131-
<?php settings_fields('es_optimizer_settings'); ?>
131+
<?php
132+
settings_fields('es_optimizer_settings');
133+
wp_nonce_field('es_optimizer_settings_action', 'es_optimizer_settings_nonce');
134+
?>
132135

133136
<table class="form-table">
134137
<?php
@@ -248,7 +251,7 @@ function es_optimizer_render_additional_options($options) {
248251
$options,
249252
'dns_prefetch_domains',
250253
esc_html__('DNS Prefetch Domains', 'Simple-WP-Optimizer'),
251-
esc_html__('Enter one domain per line. Include the full URL (e.g., https://fonts.googleapis.com)', 'Simple-WP-Optimizer')
254+
esc_html__('Enter one HTTPS domain per line (e.g., https://fonts.googleapis.com). Only secure HTTPS domains are allowed for security reasons.', 'Simple-WP-Optimizer')
252255
);
253256

254257
// Jetpack Ads settings
@@ -355,8 +358,9 @@ function es_optimizer_render_textarea_option($options, $optionName, $title, $des
355358
* Validate options before saving
356359
*
357360
* This function implements a security-focused validation system:
358-
* 1. Checkboxes are validated to ensure they contain only boolean values (0 or 1)
359-
* 2. DNS prefetch domains undergo multiple validation steps:
361+
* 1. Verifies WordPress nonce for CSRF protection
362+
* 2. Checkboxes are validated to ensure they contain only boolean values (0 or 1)
363+
* 3. DNS prefetch domains undergo multiple validation steps:
360364
* - Trimming to remove unwanted whitespace
361365
* - Empty value checking
362366
* - URL validation via filter_var()
@@ -366,6 +370,22 @@ function es_optimizer_render_textarea_option($options, $optionName, $title, $des
366370
* @return array Validated and sanitized options
367371
*/
368372
function es_optimizer_validate_options($input) {
373+
// Security: Verify nonce for CSRF protection
374+
if (!isset($_POST['es_optimizer_settings_nonce']) ||
375+
!wp_verify_nonce($_POST['es_optimizer_settings_nonce'], 'es_optimizer_settings_action')) {
376+
377+
// Add admin notice for failed nonce verification
378+
add_settings_error(
379+
'es_optimizer_options',
380+
'nonce_failed',
381+
esc_html__('Security verification failed. Please try again.', 'Simple-WP-Optimizer'),
382+
'error'
383+
);
384+
385+
// Return current options without changes
386+
return get_option('es_optimizer_options', es_optimizer_get_default_options());
387+
}
388+
369389
$valid = array();
370390

371391
// Validate checkboxes (0 or 1)
@@ -379,23 +399,65 @@ function es_optimizer_validate_options($input) {
379399
$valid[$checkbox] = isset($input[$checkbox]) ? 1 : 0;
380400
}
381401

382-
// Validate and sanitize the DNS prefetch domains
402+
// Validate and sanitize the DNS prefetch domains with enhanced security
383403
if (isset($input['dns_prefetch_domains'])) {
384404
$domains = explode("\n", trim($input['dns_prefetch_domains']));
385405
$sanitizedDomains = array();
406+
$rejectedDomains = array();
386407

387408
foreach ($domains as $domain) {
388409
$domain = trim($domain);
389410
if (!empty($domain)) {
390-
// Basic URL validation
411+
// Enhanced URL validation with security checks
391412
if (filter_var($domain, FILTER_VALIDATE_URL)) {
392-
// Security: Use esc_url_raw to sanitize URLs before storing in database
393-
// This prevents potential security issues with malformed URLs
394-
$sanitizedDomains[] = esc_url_raw($domain);
413+
$parsedUrl = parse_url($domain);
414+
415+
// Security: Enforce HTTPS-only domains for DNS prefetch
416+
if (isset($parsedUrl['scheme']) && $parsedUrl['scheme'] === 'https') {
417+
// Additional security checks
418+
if (isset($parsedUrl['host'])) {
419+
$host = $parsedUrl['host'];
420+
421+
// Prevent localhost and private IP ranges for security
422+
if (!in_array($host, array('localhost', '127.0.0.1', '::1')) &&
423+
!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
424+
425+
// Security: Use esc_url_raw to sanitize URLs before storing in database
426+
// This prevents potential security issues with malformed URLs
427+
$sanitizedDomains[] = esc_url_raw($domain);
428+
} else {
429+
$rejectedDomains[] = $domain . ' (private/local address not allowed)';
430+
}
431+
}
432+
} else {
433+
$rejectedDomains[] = $domain . ' (HTTPS required for security)';
434+
}
435+
} else {
436+
$rejectedDomains[] = $domain . ' (invalid URL format)';
395437
}
396438
}
397439
}
398440

441+
// Show admin notice if any domains were rejected for security reasons
442+
if (!empty($rejectedDomains)) {
443+
// Security: Properly escape and limit the rejected domains in error messages
444+
$escapedRejectedDomains = array_map('esc_html', array_slice($rejectedDomains, 0, 3));
445+
$rejectedMessage = implode(', ', $escapedRejectedDomains);
446+
if (count($rejectedDomains) > 3) {
447+
$rejectedMessage .= esc_html__('...', 'Simple-WP-Optimizer');
448+
}
449+
450+
add_settings_error(
451+
'es_optimizer_options',
452+
'dns_prefetch_security',
453+
sprintf(
454+
esc_html__('Some DNS prefetch domains were rejected for security reasons: %s', 'Simple-WP-Optimizer'),
455+
$rejectedMessage
456+
),
457+
'warning'
458+
);
459+
}
460+
399461
$valid['dns_prefetch_domains'] = implode("\n", $sanitizedDomains);
400462
}
401463

0 commit comments

Comments
 (0)