## https://sploitus.com/exploit?id=327A711D-523D-52F8-A8E8-1674527BB00D
# CVE-2025-68999
**Happy Addons for Elementor <= 3.20.4** โ Authenticated (Contributor+) Second-Order SQL Injection
| | |
|---|---|
| **CVSS** | 8.5 HIGH |
| **Affected** | <= 3.20.4 |
| **Patched** | 3.20.6 |
| **Min. role** | Contributor (`edit_posts`) |
| **Vector** | Network / Low complexity / Low privileges |
## The bug
`duplicate_meta_entries()` in `classes/clone-handler.php` copies post meta rows to a cloned post using a hand-rolled bulk INSERT. It fetches the rows safely with `$wpdb->prepare()`, but then drops `$entry->meta_key` straight into the SQL string without escaping:
```php
$_records[] = "( $duplicated_post_id, '{$entry->meta_key}', '{$_value}' )";
// ...
$wpdb->query( $query );
```
Because `meta_key` comes from the database, the code treats it as trusted. But Contributors can set arbitrary field names via the Custom Fields panel โ so they control what's in that column.
The attack is two steps:
1. **Write:** store a malicious string as a custom field name. `add_post_meta()` handles this safely โ the payload lands in the DB without executing anything.
2. **Trigger:** click Happy Clone. `duplicate_meta_entries()` reads the key back and concatenates it into the raw INSERT. MySQL executes the injected subquery.
Static analysis misses this because the source of dangerous data is a DB read (`$wpdb->get_results()`), which taint engines mark as sanitized. The storage boundary breaks the taint chain.
## Impact
Any Contributor can extract:
- Password hashes for all users (crack offline โ hashcat mode 400)
- WordPress secret keys / salts (forge persistent auth cookies)
- Any row from `wp_options` (API keys, payment credentials)
- Private post content
400K+ active installs were affected at disclosure time.
## Usage
```bash
pip install requests
python3 poc.py https://target.com contributor p4ss
```
The script authenticates over HTTP, stores the injection payload as a custom field name, triggers the Happy Clone action, and reads the leaked hash from the cloned post's meta fields. Output is saved to `hash.txt`.
```bash
hashcat -m 400 hash.txt rockyou.txt
```
## Full writeup
https://folks-iwd.github.io/writeups/cve-2025-68999.html
## Disclosure timeline
| Date | Event |
|------|-------|
| December 2025 | Discovered via SVN diff. PoC confirmed. |
| December 2025 | Reported to Patchstack Alliance with full writeup and PoC. |
| January 2026 | weDevs shipped the fix in v3.20.6. |
| January 23, 2026 | CVE-2025-68999 published. CVSS 8.5 HIGH assigned. |
## The patch
weDevs replaced the entire hand-rolled INSERT with:
```php
foreach ( $entries as $entry ) {
update_post_meta( $duplicated_post_id, $entry->meta_key, $entry->meta_value );
}
```
`update_post_meta()` internally calls `$wpdb->update()` with prepared statements for both key and value.