Security Advisory: SQL Injection Vulnerability in CartToFamily.php
Date: December 06, 2025
Reporter: Guilherme Mury
Severity: High / Critical
Affected Component: /src/CartToFamily.php
Vulnerability Type: SQL Injection (CWE-89)
π Introduction
Hello ChurchCRM Team,
First of all, thank you for maintaining this project. While conducting a source code review of the application to study its security patterns, I identified a SQL Injection vulnerability in the "Add to Family" feature.
I am reporting this responsibly to ensure the security of the users relying on this software. Below is a detailed analysis of the issue, why it happens, and how to fix it using the project's existing security standards.
π¨ Vulnerability Details
The vulnerability exists in the src/CartToFamily.php file, specifically in how the PersonAddress POST parameter is handled.
Unlike other parameters in the same file which are correctly cast to integers using your InputUtils class, the PersonAddress parameter is missing the type definition. This allows an attacker to inject arbitrary SQL commands directly into the query.
π Root Cause Analysis (Comparative)
The issue is best understood by comparing two lines of code within the same file (src/CartToFamily.php):
1. The Secure Pattern (Line 18):
$iFamilyID = InputUtils::legacyFilterInput($_POST['FamilyID'], 'int');
- Observation: Here, the developer correctly passed the
'int' flag as the second argument. This forces InputUtils to cast the input to an integer, neutralizing any malicious string characters. This is secure.
2. The Vulnerable Pattern (Line 29 - The Issue):
$iPersonAddress = InputUtils::legacyFilterInput($_POST['PersonAddress']);
- Observation: Here, the
'int' flag is missing. The function defaults to treating the input as a string.
- The Exploit: Because the subsequent SQL query (Line 32) does not use quotes around the variable, an attacker does not even need to "break out" using quotes. They can simply append SQL logic.
Vulnerable Query (Line 32):
$sSQL = 'SELECT * FROM person_per WHERE per_ID = ' . $iPersonAddress;
π₯ Proof of Concept (PoC)
An attacker with "Add Records" permission can exploit this vulnerability to extract sensitive data from the database (e.g., admin credentials) or bypass logic checks.
Steps to Reproduce:
- Log in as a user with
Add Records permission.
- Add a person to the cart.
- Navigate to the "Cart to Family" page.
- Intercept the
POST request when submitting the form.
- Modify the
PersonAddress parameter in the body:
Payload Example (Boolean-Based):
Resulting Query Executed:
SELECT * FROM person_per WHERE per_ID = 1 OR 1=1
- Result: The application will retrieve all user records instead of just the intended one, potentially exposing PII (Personally Identifiable Information) of the entire congregation in the subsequent logic.
Payload Example (Union-Based - Theoretical):
PersonAddress=0 UNION SELECT 1,2,3,4,usr_Password,6... FROM user_usr
- Result: Allows extraction of data from other tables, such as admin password hashes.
π‘οΈ Remediation (The Fix)
The fix is simple and aligns with the coding style already present in the file. You simply need to enforce the integer type on the input.
Vulnerable Code:
$iPersonAddress = InputUtils::legacyFilterInput($_POST['PersonAddress']);
Patched Code:
$iPersonAddress = InputUtils::legacyFilterInput($_POST['PersonAddress'], 'int');
By adding the 'int' argument, InputUtils will ensure that $iPersonAddress is strictly a number, making the SQL Injection impossible.
π€ Conclusion
This vulnerability appears to be an oversight where the security pattern used in line 18 was not applied to line 29. A simple one-line change will fully mitigate the risk.
Please let me know if you need further assistance or if you would like me to open a Pull Request with the fix (though I recommend handling it via a private security PR first).
Best regards,
Guilherme Mury
Security Researcher
Security Advisory: SQL Injection Vulnerability in
CartToFamily.phpDate: December 06, 2025
Reporter: Guilherme Mury
Severity: High / Critical
Affected Component:
/src/CartToFamily.phpVulnerability Type: SQL Injection (CWE-89)
π Introduction
Hello ChurchCRM Team,
First of all, thank you for maintaining this project. While conducting a source code review of the application to study its security patterns, I identified a SQL Injection vulnerability in the "Add to Family" feature.
I am reporting this responsibly to ensure the security of the users relying on this software. Below is a detailed analysis of the issue, why it happens, and how to fix it using the project's existing security standards.
π¨ Vulnerability Details
The vulnerability exists in the
src/CartToFamily.phpfile, specifically in how thePersonAddressPOST parameter is handled.Unlike other parameters in the same file which are correctly cast to integers using your
InputUtilsclass, thePersonAddressparameter is missing the type definition. This allows an attacker to inject arbitrary SQL commands directly into the query.π Root Cause Analysis (Comparative)
The issue is best understood by comparing two lines of code within the same file (
src/CartToFamily.php):1. The Secure Pattern (Line 18):
'int'flag as the second argument. This forcesInputUtilsto cast the input to an integer, neutralizing any malicious string characters. This is secure.2. The Vulnerable Pattern (Line 29 - The Issue):
'int'flag is missing. The function defaults to treating the input as a string.Vulnerable Query (Line 32):
π₯ Proof of Concept (PoC)
An attacker with "Add Records" permission can exploit this vulnerability to extract sensitive data from the database (e.g., admin credentials) or bypass logic checks.
Steps to Reproduce:
Add Recordspermission.POSTrequest when submitting the form.PersonAddressparameter in the body:Payload Example (Boolean-Based):
PersonAddress=1 OR 1=1Resulting Query Executed:
Payload Example (Union-Based - Theoretical):
PersonAddress=0 UNION SELECT 1,2,3,4,usr_Password,6... FROM user_usrπ‘οΈ Remediation (The Fix)
The fix is simple and aligns with the coding style already present in the file. You simply need to enforce the integer type on the input.
Vulnerable Code:
Patched Code:
By adding the
'int'argument,InputUtilswill ensure that$iPersonAddressis strictly a number, making the SQL Injection impossible.π€ Conclusion
This vulnerability appears to be an oversight where the security pattern used in line 18 was not applied to line 29. A simple one-line change will fully mitigate the risk.
Please let me know if you need further assistance or if you would like me to open a Pull Request with the fix (though I recommend handling it via a private security PR first).
Best regards,
Guilherme Mury
Security Researcher