CVE-2025-66291 - Unauthorized Access to Interview Attachments via Direct Object Reference in OrangeHRM Recruitment Module
Author and Researcher

Ravindu Wickramasinghe
@rvz
1. Description
The Interview Attachment endpoint in the OrangeHRM Recruitment module incorrectly authorizes access based solely on a valid session cookie and predictable URL parameters. A user with only ESS (Employee Self-Service) privileges - who has no access to recruitment workflows or interview-related data - can directly retrieve uploaded interview attachments by accessing the vulnerable endpoint with arbitrary interview and attachment IDs.
This results in unauthorized exposure of sensitive interview files such as candidate CVs, evaluations, and supporting documents. The flaw stems from missing server-side authorization checks before serving the file, allowing low-privileged accounts to bypass access controls and retrieve confidential hiring data. The endpoint serves files based on predictable object identifiers and session presence rather than validating the user's association with the relevant recruitment process.
Affected versions: OrangeHRM >= 5.0, <= 5.7
Patched version: 5.8
2. Technical Details
The vulnerable endpoint follows a predictable pattern where both the interview ID and attachment ID are sequential integers:
GET /web/index.php/recruitment/viewInterviewAttachment/interview/{interviewId}/attachment/{attachmentId} HTTP/1.1Cookie: orangehrm=<ESS-user-session>The attachment retrieval API at /api/v2/recruitment/interviews/{id}/attachments is properly restricted - only users with Recruitment module access can list attachments. However, the file download endpoint (viewInterviewAttachment) performs no equivalent authorization check. It validates only that the session cookie belongs to an authenticated user, regardless of their role or module access.
This creates a classic IDOR condition: the listing endpoint is protected, but the actual resource retrieval is not. An attacker who can guess or enumerate interview and attachment IDs - which are sequential integers - can download any interview attachment in the system.
3. Steps to Reproduce
- Log in as an admin user, create a vacancy, and publish it.
- Apply to the vacancy from the job posting link as an external user.
- As the admin user, shortlist the candidate and move forward to the interview stage.
- In Recruitment > Candidates, select the candidate and click the attachment icon under the "Candidate History" section for the interview stage.
- Add an attachment and observe the API call to:The response contains the attachment ID.terminal
GET /api/v2/recruitment/interviews/1/attachments?limit=50&offset=0 - Log in as an ESS user with no access to the Recruitment module.
- Send the following request using the ESS user's session cookie:terminal
GET /web/index.php/recruitment/viewInterviewAttachment/interview/1/attachment/{attachment-id} HTTP/1.1Cookie: orangehrm=<ESS-session-cookie> - The server returns the interview attachment file without enforcing proper authorization - the ESS user receives confidential interview documents they should have no access to.
4. CVSS
CVSS 4.0 Score: 5.3 (Moderate)
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N
5. Recommendations
Implement strict server-side authorization checks to ensure only authorized users with valid access rights to the Recruitment module and corresponding interview records can retrieve attachments. Validate that the requesting user is explicitly associated with the relevant recruitment workflow and interview record before serving files. The viewInterviewAttachment endpoint must enforce the same role-based access controls applied to the attachment listing API.
