Summary
A critical SQL Injection vulnerability exists in the legacy endpoint /Reports/ConfirmReportEmail.php in ChurchCRM 6.3.0. Although the feature was removed from the UI, the file remains deployed and reachable directly via URL. This is a classic case of dead but reachable code. Any authenticated user - including one with zero assigned permissions - can exploit SQL injection through the familyId parameter.
Details
The issue is located in:
src/Reports/ConfirmReportEmail.php
Vulnerable code (lines 82–83):
if (InputUtils::legacyFilterInput($_GET['familyId'], 'int')) {
$sSubQuery = ' and fam_id in (' . $_GET['familyId'] . ') ';
}
Why this is vulnerable:
- The return value of
legacyFilterInput() is ignored entirely.
- The raw
$_GET['familyId'] value is concatenated directly into a SQL query.
- No escaping, quoting, type enforcement, or parameter binding is applied.
- Because the endpoint is no longer referenced in the UI, it does not benefit from updated framework security controls.
Dead but reachable endpoint:
/Reports/ConfirmReportEmail.php?familyId=<value>
Normal behavior:
302 Redirect → /v2/family/<id>&PDFEmailed=
Malicious payloads containing ) or -- break redirect logic and execute the vulnerable SQL.
Even a user with zero permissions can exploit the vulnerability.
A SLEEP(5) payload reliably delays the response, proving SQL execution.
PoC
Authenticated user visits:
http://localhost:8101/Reports/ConfirmReportEmail.php?familyId=1)%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))a)%20--%20-
Observed result:
- Response delayed by ~5 seconds → success.
- Redirect suppressed.
- Vulnerable SQL executed.
sqlmap confirmation:
Impact
- Complete database compromise (read/write/delete)
- Extraction of all sensitive ChurchCRM data
- Possible privilege escalation
- Potential for RCE depending on SQL functions and configuration
- Vulnerable endpoint is reachable despite being removed from UI
Summary
A critical SQL Injection vulnerability exists in the legacy endpoint
/Reports/ConfirmReportEmail.phpin ChurchCRM 6.3.0. Although the feature was removed from the UI, the file remains deployed and reachable directly via URL. This is a classic case of dead but reachable code. Any authenticated user - including one with zero assigned permissions - can exploit SQL injection through thefamilyIdparameter.Details
The issue is located in:
src/Reports/ConfirmReportEmail.phpVulnerable code (lines 82–83):
Why this is vulnerable:
legacyFilterInput()is ignored entirely.$_GET['familyId']value is concatenated directly into a SQL query.Dead but reachable endpoint:
Normal behavior:
Malicious payloads containing
)or--break redirect logic and execute the vulnerable SQL.Even a user with zero permissions can exploit the vulnerability.
A
SLEEP(5)payload reliably delays the response, proving SQL execution.PoC
Authenticated user visits:
Observed result:
sqlmap confirmation:
Impact