CVE-2025-52050
📋 TL;DR
This SQL injection vulnerability in Frappe ERPNext allows attackers to execute arbitrary SQL queries through the expiry_date parameter in the get_loyalty_program_details_with_points() function. This can lead to complete database compromise including extraction of sensitive business data, user credentials, and financial information. All organizations running vulnerable versions of ERPNext are affected.
💻 Affected Systems
- Frappe ERPNext
📦 What is this software?
Erpnext by Frappe
⚠️ Risk & Real-World Impact
Worst Case
Complete database compromise leading to data exfiltration, privilege escalation, authentication bypass, and potential lateral movement to other systems.
Likely Case
Extraction of sensitive business data including customer information, financial records, and user credentials from the ERPNext database.
If Mitigated
Limited impact if proper input validation and parameterized queries are implemented, with database permissions restricted to minimum necessary.
🎯 Exploit Status
Exploitation requires understanding of SQL injection techniques and knowledge of the vulnerable parameter. The vulnerability is in a specific function with limited public documentation.
🛠️ Fix & Mitigation
✅ Official Fix
Patch Version: Fixed in commit 8696ba2f5d9e99c799d4aef577f72f2fae5678e7
Vendor Advisory: https://github.com/frappe/erpnext/pull/49192/commits/8696ba2f5d9e99c799d4aef577f72f2fae5678e7
Restart Required: No
Instructions:
1. Update to the latest version of ERPNext that includes the fix. 2. Apply the specific commit 8696ba2f5d9e99c799d4aef577f72f2fae5678e7 if not updating to latest version. 3. Verify the fix by checking that parameterized queries are used in the get_loyalty_program_details_with_points() function.
🔧 Temporary Workarounds
Input Validation Workaround
allImplement strict input validation for the expiry_date parameter to only accept valid date formats
# Add input validation in the function to ensure expiry_date matches YYYY-MM-DD format
# Example Python validation: import re; if not re.match(r'^\d{4}-\d{2}-\d{2}$', expiry_date): raise ValueError('Invalid date format')
WAF Rule Implementation
allDeploy web application firewall rules to block SQL injection patterns in the expiry_date parameter
# Add WAF rule to block SQL keywords in the expiry_date parameter
# Example ModSecurity rule: SecRule ARGS:expiry_date "@detectSQLi" "id:1001,phase:2,deny,status:403"
🧯 If You Can't Patch
- Implement strict input validation and sanitization for all user inputs in the loyalty program module
- Restrict database user permissions to read-only for the application where possible
🔍 How to Verify
Check if Vulnerable:
Check if your ERPNext version is 15.57.5 or earlier by examining the code in erpnext/accounts/doctype/loyalty_program/loyalty_program.py for the vulnerable get_loyalty_program_details_with_points() function
Check Version:
bench version or check the version.txt file in the ERPNext installation directory
Verify Fix Applied:
Verify that the function now uses parameterized queries (SQL with placeholders) instead of string concatenation for the expiry_date parameter
📡 Detection & Monitoring
Log Indicators:
- Unusual SQL queries in database logs containing UNION, SELECT, INSERT, or DROP commands
- Multiple failed authentication attempts followed by access to loyalty program endpoints
- Unusual patterns in expiry_date parameter values containing SQL keywords
Network Indicators:
- Unusual traffic patterns to /api/method/erpnext.accounts.doctype.loyalty_program.loyalty_program.get_loyalty_program_details_with_points endpoint
- Large data transfers from the ERPNext server to external IPs
SIEM Query:
source="erpnext_logs" AND (message="*expiry_date*SELECT*" OR message="*expiry_date*UNION*" OR message="*expiry_date*FROM*")