Security improvements and API compatibility fixes (v0.3.6)

- Add recursive key sorting for response signing compatibility
- Fix IP header spoofing in rate limiting with trusted proxy support
- Add CSRF protection to CSV export with nonce verification
- Explicit Twig autoescape for XSS prevention
- Escape status values in CSS classes
- Update README with security documentation and trusted proxy config
- Update translations for v0.3.6

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-23 21:18:32 +01:00
parent c7967f71ab
commit 35d802c2b8
11 changed files with 669 additions and 392 deletions

View File

@@ -572,6 +572,11 @@ final class AdminController
*/
private function handleCsvExport(): void
{
// Verify nonce for CSRF protection
if (!wp_verify_nonce($_GET['_wpnonce'] ?? '', 'export_licenses_csv')) {
wp_die(__('Security check failed.', 'wc-licensed-product'));
}
if (!current_user_can('manage_woocommerce')) {
wp_die(__('You do not have permission to export licenses.', 'wc-licensed-product'));
}
@@ -954,7 +959,7 @@ final class AdminController
<span class="dashicons dashicons-admin-network"></span>
<?php esc_html_e('Manage Licenses', 'wc-licensed-product'); ?>
</a>
<a href="<?php echo esc_url(admin_url('admin.php?page=wc-licenses&action=export_csv')); ?>" class="button">
<a href="<?php echo esc_url(wp_nonce_url(admin_url('admin.php?page=wc-licenses&action=export_csv'), 'export_licenses_csv')); ?>" class="button">
<span class="dashicons dashicons-download"></span>
<?php esc_html_e('Export to CSV', 'wc-licensed-product'); ?>
</a>
@@ -1048,6 +1053,12 @@ final class AdminController
$this->twig->addFunction(new \Twig\TwigFunction('transfer_nonce', function (): string {
return wp_create_nonce('transfer_license');
}));
$this->twig->addFunction(new \Twig\TwigFunction('export_csv_url', function (): string {
return wp_nonce_url(
admin_url('admin.php?page=wc-licenses&action=export_csv'),
'export_licenses_csv'
);
}));
try {
echo $this->twig->render('admin/licenses.html.twig', [
@@ -1187,7 +1198,7 @@ final class AdminController
?>
<div class="wrap">
<h1 class="wp-heading-inline"><?php esc_html_e('Licenses', 'wc-licensed-product'); ?></h1>
<a href="<?php echo esc_url(admin_url('admin.php?page=wc-licenses&action=export_csv')); ?>" class="page-title-action">
<a href="<?php echo esc_url(wp_nonce_url(admin_url('admin.php?page=wc-licenses&action=export_csv'), 'export_licenses_csv')); ?>" class="page-title-action">
<span class="dashicons dashicons-download" style="vertical-align: middle;"></span>
<?php esc_html_e('Export CSV', 'wc-licensed-product'); ?>
</a>