# www.drivegrab.com SQL injection

Unauthenticated AJAX form-preview endpoint in Formidable Pro WordPress plugin let attacker inject SQL via [display-frm-data] shortcode order param, enabling blind boolean extraction of the WordPress database.

- Payout: $4,500
- Severity: high
- Program: Grab
- Credited: jouko
- Disclosed: 2017-11-17
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/273946
- Library page: https://bugbountylibrary.com/r/h1%3A273946
- Tags: domain:web impact:data-leak impact:pii-leak kind:bounty platform:hackerone sev:high tech:php tech:wordpress technique:blind technique:source-review vuln:access-control vuln:sqli

**Target:** WordPress Formidable Pro plugin admin-ajax.php frm_forms_preview
**Root cause:** The frm_forms_preview AJAX action is exposed to unauthenticated users and renders user-supplied HTML containing shortcodes; the [display-frm-data] shortcode passes the order/order_by parameters unsanitized into the ORDER BY clause of an intermediate SQL query.
**Steps:**
1. Confirm unauthenticated preview: `curl -s -i 'https://www.drivegrab.com/wp-admin/admin-ajax.php' --data 'action=frm_forms_preview'`
2. Confirm HTML injection: `--data 'action=frm_forms_preview&after_html=hello world'`
3. Confirm shortcode execution: `after_html=XXX[display-frm-data id=835]YYY`
4. Inject into order param: `after_html=XXX[display-frm-data id=835 order_by=id limit=1 order=zzz]YYY` and observe SQL error in logs
5. Exploit blind via sqlmap with `--technique B --string persondetailstable`, `--eval` to repair comma-mangled SELECT, and `commalesslimit` tamper
6. Dump tables, admin password hashes, webroot path
**How found:** Noticed the frm_forms_preview AJAX action was reachable unauthenticated, then that after_html accepted WordPress shortcodes; enumerated Formidable shortcodes and found [display-frm-data] with order/order_by params reaching SQL.
**Exploitation:** Unauthenticated attacker sends POST to admin-ajax.php with action=frm_forms_preview and after_html containing [display-frm-data] shortcode whose order parameter carries injected SQL. Injected expression lands in ORDER BY of an intermediate query fetching entry IDs; attacker infers one bit per request by observing entry ordering on the rendered page (boolean blind). Comma handling in the plugin required an --eval repair (`true=true.replace(",",",-it.id%2b")`) and commalesslimit tamper to keep queries valid. Extracted DB tables, admin password hashes, and webroot path.
**Escalation:** Attempted pivot from DB to WordPress admin via iThemes-Sync authentication key stored in plaintext, but RCE could not be confirmed (hash salt validation failed); Grab also noted server hardening blocked the pivot.
**Insight:** WordPress plugin AJAX actions registered without capability checks (admin-only preview functions) are prime unauthenticated surfaces; shortcode attributes like order/order_by that map to SQL ORDER BY are commonly unsanitized, and blind extraction is still possible when output ordering is attacker-controllable.
