From 36b51c9fc88bf00793191f8e3004359637c5c0f2 Mon Sep 17 00:00:00 2001 From: magdev Date: Fri, 23 Jan 2026 21:22:26 +0100 Subject: [PATCH] Update CLAUDE.md with v0.3.6 session history - Document security hardening changes (CSRF, IP spoofing, XSS) - Add recursive key sorting fix for response signing - Document trusted proxy configuration - Add release information (SHA256, package size) Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 9e6454f..c4f5917 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -36,7 +36,7 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w No known bugs at the moment. -### Version 0.3.6 +### Version 0.3.7 No changes at the moment. @@ -978,3 +978,57 @@ Added admin dashboard widget for license statistics and automatic license expira - `autoExpireLicense()` updates status to expired and returns true if changed - LicenseExpiredEmail follows same pattern as LicenseExpirationEmail (warning vs expired) - Expired notification tracked via user meta to prevent duplicate emails + +### 2026-01-23 - Version 0.3.6 - Security Hardening + +**Overview:** + +Security audit and implementation alignment with client/server documentation. Fixed response signing compatibility, rate limiting security, and XSS prevention. + +**Security Fixes:** + +- Added CSRF protection (nonce verification) to CSV export functionality +- Fixed IP header spoofing vulnerability in rate limiting - now requires explicit trusted proxy configuration +- Enabled explicit Twig autoescape (`'html'`) for XSS protection +- Fixed unescaped status values in CSS class names in Twig templates + +**Implementation Fixes:** + +- Fixed response signing to use recursive key sorting for client library compatibility +- ResponseSigner now recursively sorts nested array keys alphabetically as required by `magdev/wc-licensed-product-client` + +**Modified files:** + +- `src/Api/ResponseSigner.php` - Added `recursiveKeySort()` method for proper signature generation +- `src/Api/RestApiController.php` - Added trusted proxy support with `isTrustedProxy()`, `isCloudflareIp()`, `ipMatchesCidr()` methods +- `src/Plugin.php` - Added explicit `autoescape => 'html'` to Twig environment +- `src/Admin/AdminController.php` - Added nonce verification to `handleCsvExport()`, added `export_csv_url()` Twig function +- `templates/frontend/licenses.html.twig` - Added `esc_attr()` for CSS class status +- `templates/admin/licenses.html.twig` - Added `esc_attr()` for CSS class status, updated export link to use `export_csv_url()` + +**Configuration:** + +To enable trusted proxy support for rate limiting, add to `wp-config.php`: + +```php +// For Cloudflare +define('WC_LICENSE_TRUSTED_PROXIES', 'CLOUDFLARE'); + +// Or for specific IPs/CIDR ranges +define('WC_LICENSE_TRUSTED_PROXIES', '10.0.0.1,192.168.1.0/24'); +``` + +**Technical notes:** + +- Rate limiting now only trusts proxy headers (`HTTP_CF_CONNECTING_IP`, `HTTP_X_FORWARDED_FOR`, `HTTP_X_REAL_IP`) when `WC_LICENSE_TRUSTED_PROXIES` constant is defined +- Without trusted proxy configuration, rate limiting uses `REMOTE_ADDR` only (prevents IP spoofing) +- Cloudflare IP ranges are hardcoded for convenience (as of 2024) +- CIDR notation supported for custom proxy ranges +- Recursive key sorting ensures signature compatibility with SecureLicenseClient +- References: + +**Release v0.3.6:** + +- Created release package: `releases/wc-licensed-product-0.3.6.zip` (818 KB) +- SHA256: `b0063f0312759f090e12faba83de730baf4114139d763e46fad2b781d4b38270` +- Tagged as `v0.3.6` and pushed to `main` branch