Skip to content

Fix: Stored XSS in profile display name consent logs and IDOR in quiz builder question deletion - #3032

Closed
shewa12 wants to merge 1 commit into
devfrom
fix/security-xss-profile-consent-and-quizbuilder-idor
Closed

shewa12 wants to merge 1 commit into
devfrom
fix/security-xss-profile-consent-and-quizbuilder-idor

Conversation

@shewa12

@shewa12 shewa12 commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR resolves two critical security vulnerabilities:

  1. Authenticated Stored Cross-Site Scripting (XSS) in Profile Display Name & Consent Logs

    • Affected Areas: classes/Student.php, GDPR/Controllers/UserConsent.php, assets/src/js/admin-dashboard/segments/consent-logs.js, and assets/src/js/admin-dashboard/segments/students.js.
    • Vulnerability Details: When a user registers or updates profile information (display_name, first_name, last_name), standard sanitization retains HTML entity sequences. When these values are rendered into HTML data attributes (such as data-user-name) in consent logs, browser dataset.userName access automatically decodes entities. Injecting this unescaped string directly into modalBody.innerHTML causes script execution in the admin dashboard context.
    • Remediation:
      • Sanitized input on the backend using wp_strip_all_tags( wp_specialchars_decode( ..., ENT_QUOTES ) ) in Student.php and UserConsent.php.
      • Replaced raw template string interpolation into innerHTML with safe DOM textContent assignment in consent-logs.js and students.js.
  2. Insecure Direct Object Reference (IDOR) in Quiz Builder Question & Answer Deletion

    • Affected Areas: classes/QuizBuilder.php.
    • Vulnerability Details: QuizBuilder::handle_delete() executed SQL deletions for deleted_question_ids and deleted_answer_ids without verifying that the targets belong to the quiz or course being edited. An authenticated instructor could submit question or answer IDs belonging to quizzes from other courses/instructors and have them deleted.
    • Remediation:
      • Added authorization check tutor_utils()->can_user_manage( "quiz", $quiz_id ) in validate_payload().
      • Scoped handle_delete() with $quiz_id, filtering deleted question IDs and answer IDs to ensure they strictly belong to the quiz being updated before executing database deletion queries.
      • Safely populated quiz question/answer tracking arrays to prevent PHP type errors when payloads lack questions.

@shewa12 shewa12 added the Security Fix Security vulnerability fix label Sep 24, 2026
@shewa12
shewa12 requested a review from harunollyo September 24, 2026 10:04
@shewa12 shewa12 closed this Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Security Fix Security vulnerability fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant