
ERPNext v16.25.0 - Improper authorization in Prospect opportunities API
7.1
High
Discovered by
Offensive Team, Fluid Attacks
Summary
Full name
ERPNext v16.25.0 - Improper authorization in Prospect opportunities API exposing CRM pipeline data
Code name
State
Public
Release date
Affected product
ERPNext
Vendor
Frappe
Affected version(s)
<15.115.0, <16.26.0
Fixed version(s)
>=15.115.0 - >=16.26.0
Vulnerability name
Improper authorization control for web services
Vulnerability type
Remotely exploitable
Yes
CVSS v4.0 vector string
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
CVSS v4.0 base score
7.1
Exploit available
Yes
CVE ID(s)
Description
An Improper Authorization vulnerability exists in ERPNext version <v16.25.0 and <15.115.0 due to insufficient access control in the whitelisted API method erpnext.crm.doctype.prospect.prospect.get_opportunities.
The endpoint allows authenticated users to retrieve CRM Opportunity records for an arbitrary Prospect name supplied by the caller. Because the method is exposed through a whitelisted API and does not enforce role-based or document-level permission checks before querying data with frappe.get_all(...), low-privileged users can access opportunity information that would normally be restricted by ERPNext/Frappe permissions.
Successful exploitation allows unauthorized disclosure of sensitive CRM data, including opportunity identifiers, sales owners, stages, statuses, expected closing dates, probabilities, opportunity amounts, currencies, contact names, email addresses, phone numbers, and creation timestamps.
Vulnerability
Root cause
HTTP exposure through a whitelisted method (
erpnext/crm/doctype/prospect/prospect.py:145-146):@frappe.whitelist()makes the method callable through/api/method/.... The method is not declared withallow_guest=True, so a session is required, but there is no role check such asfrappe.only_for(...)and no document permission check against the requestedProspector returnedOpportunityrecords.User-controlled object selector (
erpnext/crm/doctype/prospect/prospect.py:149):The caller controls
prospect. If they know or can discover a Prospect name, they can request opportunities linked to that Prospect.Permission bypass in query helper (
erpnext/crm/doctype/prospect/prospect.py:147):In Frappe,
frappe.get_allis explicitly documented as not checking permissions and setsignore_permissions = Truebefore delegating toget_list. This bypasses both role-based record filtering and field-level read filtering that a permission-aware query would apply.Sensitive returned fields (
erpnext/crm/doctype/prospect/prospect.py:150-163):The endpoint returns commercially sensitive CRM data and contact information, not only public identifiers.
Authorization impact
The vulnerable path is not unauthenticated, but it is reachable by any authenticated user who can call whitelisted methods. A user without the required CRM roles or record access can retrieve opportunities for a supplied Prospect name because the method does not call a permission-aware API such as frappe.get_list, frappe.has_permission, or frappe.get_doc(...).check_permission(...).
If Prospect names are predictable, leaked, or obtainable through other application views, repeated calls can expose a broader CRM pipeline.
Relevant code:
erpnext/crm/doctype/prospect/prospect.py:137-156erpnext/crm/doctype/prospect/prospect.json:229-262erpnext/crm/doctype/opportunity/opportunity.json:661-685frappe/__init__.py:get_all
PoC
Preconditions
ERPNext v16.25.0.
A valid low-privileged user account.
At least one Prospect linked to one or more Opportunities.
ERPNext reachable at
http://localhost:8080.
Step 1 - Login as a low-privileged user
Expected result:
The response shows a successful authenticated session.
In the submitted evidence, the response included:
Step 2 - Request opportunities for a Prospect
Expected vulnerable result:
The endpoint returns Opportunity records despite the caller being a low-privileged authenticated user.
The response contains sales pipeline and contact fields.
Example observed response:
Evidence of Exploitation
Video of exploitation:
Static evidence:

Our security policy
We have reserved the ID CVE-2026-13227 to refer to this issue from now on.
System Information
Frappe ERPNext.
Version: <15.115.0, <16.26.0.
Operating System: Any
References
GitHub Repository: https://github.com/frappe/erpnext
Vendor Advisory: https://github.com/frappe/erpnext/security/advisories/GHSA-g8r3-82j6-wp48
Patch: https://github.com/frappe/erpnext/releases?page=2#release-v15.115.0 and https://github.com/frappe/erpnext/releases?page=2#release-v16.26.0
Mitigation
An updated version of ERPNext is available on the vendor page.
Credits
The vulnerability was discovered by Eduardo Ferguson from Fluid Attacks' Offensive Team.
Timeline
Vulnerability discovered
Vendor contacted
Vendor replied
Vendor confirmed
Vulnerability patched
Public disclosure
Does your application use this vulnerable software?
During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.












