Summary
OpenEMR's POS checkout interface accepts state-changing requests without consistently validating a CSRF token. If an authenticated billing user visits a malicious page while signed in, a cross-site request may void checkouts or regenerate invoice counters.
OpenEMR's POS checkout interface accepts state-changing requests without consistently validating a CSRF token. If an authenticated billing user visits a malicious page while signed in, a cross-site request may void checkouts or regenerate invoice counters.
Affected context
The issue occurs in OpenEMR's interface/patient_file/pos_checkout_ippf.php handling of the void, voidall, and regen operations. Risk exists when an authenticated billing user's browser can reach the interface and the request is processed without validating a CSRF token; the form_checksum check can be skipped when that parameter is omitted.
The issue occurs in OpenEMR's interface/patient_file/pos_checkout_ippf.php handling of the void, voidall, and regen operations. Risk exists when an authenticated billing user's browser can reach the interface and the request is processed without validating a CSRF token; the form_checksum check can be skipped when that parameter is omitted.
Exploit preconditions
- Attack surface: The POS checkout interface in the affected application.
- Required access: The victim must be authenticated as a billing user with access to the relevant operations.
- Trigger point: The victim's browser sends a cross-site GET request while their authenticated session is active.
- Why exploitation is possible: State-changing operations are available through GET requests, and CSRF validation can be bypassed when the optional checksum parameter is absent.
- Attack surface: The POS checkout interface in the affected application.
- Required access: The victim must be authenticated as a billing user with access to the relevant operations.
- Trigger point: The victim's browser sends a cross-site GET request while their authenticated session is active.
- Why exploitation is possible: State-changing operations are available through GET requests, and CSRF validation can be bypassed when the optional checksum parameter is absent.
Why this happens
The application performs state-changing operations through GET requests without requiring consistent CSRF token validation. Because the form_checksum integrity check is conditional, an omitted parameter can leave the request unverified. This is CWE-352: Cross-Site Request Forgery, where an application relies on a victim's authenticated browser to accept an unwanted request.
The application performs state-changing operations through GET requests without requiring consistent CSRF token validation. Because the form_checksum integrity check is conditional, an omitted parameter can leave the request unverified. This is CWE-352: Cross-Site Request Forgery, where an application relies on a victim's authenticated browser to accept an unwanted request.
Potential impact
- Checkout records could be voided without the user's intent.
- Invoice counters could be regenerated, disrupting billing workflows.
- Ledger state and financial reporting could become inaccurate.
- Audit records could reflect unauthorized or confusing changes.
- Checkout records could be voided without the user's intent.
- Invoice counters could be regenerated, disrupting billing workflows.
- Ledger state and financial reporting could become inaccurate.
- Audit records could reflect unauthorized or confusing changes.
General mitigation guidance
Common defensive patterns include:
- Require unpredictable, session-bound CSRF tokens for every state-changing request, and reject missing or invalid tokens.
- Use non-GET methods for operations that modify application state.
- Treat checksums and other integrity parameters as mandatory only when they are reliably validated; do not make security checks conditional on optional input.
- Apply authorization checks to each operation and limit billing permissions to the users who need them.
- Consider same-site cookie settings and origin checks as additional defenses, not replacements for CSRF tokens.
Common defensive patterns include:
- Require unpredictable, session-bound CSRF tokens for every state-changing request, and reject missing or invalid tokens.
- Use non-GET methods for operations that modify application state.
- Treat checksums and other integrity parameters as mandatory only when they are reliably validated; do not make security checks conditional on optional input.
- Apply authorization checks to each operation and limit billing permissions to the users who need them.
- Consider same-site cookie settings and origin checks as additional defenses, not replacements for CSRF tokens.
How teams detect issues like this
Review routes and handlers for state changes reachable through GET requests, especially when CSRF checks are optional or conditional. Static analysis and code review can look for missing token validation on mutating operations and tests that accept requests with omitted security parameters. Policy checks can prohibit state-changing GET handlers and require CSRF validation in billing workflows.
Review routes and handlers for state changes reachable through GET requests, especially when CSRF checks are optional or conditional. Static analysis and code review can look for missing token validation on mutating operations and tests that accept requests with omitted security parameters. Policy checks can prohibit state-changing GET handlers and require CSRF validation in billing workflows.

