Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAuthenticate to Horilla with low-priv account
-
DeliveryObtain valid CSRF token
-
ExploitSubmit mail body with {{ request.user.password }} traversal
-
ExecutionServer renders template with full request object
-
PersistHarvest password hashes/META/PII
-
ImpactCrack hashes offline for account takeover
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Code injection prevention, sandbox exec
MITRE ATT&CK
2 techniques across 2 tactics: Execution, Initial Access The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Requires an authenticated Horilla session (any user) plus a valid CSRF token to reach the mail-preview endpoints /recruitment/get-mail-preview/ and /employee/get-employee-mail-preview in versions 1.0.0 through pre-1.6.0/2.0.0. The attacker supplies a user-controlled mail body containing Django template expressions; exploitation works against default configurations because the vulnerable handlers pass the full request object into the template context. Limiting factors: valid authentication (PR:L) and CSRF token are mandatory, and the Django template sandbox restricts the primitive to attribute reads (information disclosure) rather than code execution, so no arbitrary RCE is achievable. |
| Impact | The CVSS 3.1 vector (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N = 6.5 Medium) is well-supported by the description and the confirmed patch: a network-reachable, low-complexity flaw requiring only a valid authenticated session, yielding high confidentiality impact (password hashes, PII, request metadata) with no integrity or availability effect. No EPSS score, no CISA KEV listing, and no public POC are provided, so exploitation status is: no public exploit identified at time of analysis. The assigned CWE-94 (Code Injection) and the 'RCE' tag OVERSTATE the issue - the description explicitly notes Django template sandbox restrictions prevent arbitrary code execution, making the true weakness server-side template attribute traversal resulting in information disclosure (CWE-200/CWE-94-limited). This is therefore a genuine but bounded credential-exposure bug, not a code-execution priority; the C:H rating is justified because leaked password hashes enable offline cracking and downstream account compromise. Because exploitation requires authentication (PR:L) and there is no evidence of in-the-wild use, real-world urgency is moderate rather than critical - prioritize behind unauthenticated or actively-exploited issues but patch promptly given credential exposure. |
| Exploit ScenarioDerived | An attacker with any valid low-privilege Horilla account and a CSRF token submits a mail-preview body containing Django template expressions such as {{ request.user.password }} or {{ request.META }} to /recruitment/get-mail-preview/ or /employee/get-employee-mail-preview. The server renders these against the full request object and returns the leaked password hashes, personal data, and request metadata, which the attacker then cracks offline to escalate. No public POC is referenced, but the commit diff confirms the exact traversal primitive. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Sep 25, 2026
An authenticated user with a valid CSRF token can read Django password hashes, request metadata, and related-user attributes from Horilla HR/CRM mail-preview functionality in versions 1.0.0 through pre-1.6.0 and prior to 2.0.0. The get_mail_preview handlers at /recruitment/get-mail-preview/ and /employee/get-employee-mail-preview render a user-supplied mail body as a Django template while the full request object sits in the template context, so template attribute traversal such as request.user.password or request.META exposes the underlying data; the Django template sandbox limits this to information disclosure rather than code execution. Exploitation requires only a low-privileged authenticated session with a CSRF token (no public exploit identified at time of analysis), and the confidentiality impact is high because the leaked password hashes can be attacked offline or used to identify accounts for follow-on compromise; vendor fixes ship in 1.6.0 and 2.0.0.
RemediationAI
Vendor-released patch: upgrade to Horilla 1.6.0 or 2.0.0 (the latter at https://github.com/horilla/horilla-hr/releases/tag/2.0.0), which introduce sanitize_mail_template_placeholders() to allowlist mail placeholders, strip all {% %} tags, and substitute a sanitized request proxy via build_safe_template_request(), and which also gate the recruitment view behind recruitment.view_candidate with a scoped candidate queryset; the underlying fixes are the commits bd3eed2168b0167f273a8dd7f218f1b37320ac39 and f1ca7cbc6216cb5bf19fc0174f49994ce5ffc2ad. If immediate upgrade is not possible, compensating controls include restricting /recruitment/get-mail-preview/ and /employee/get-employee-mail-preview at the reverse proxy or WAF to trusted HR/superuser roles only (trades away the mail-preview feature for ordinary employees), disabling or unregistering the mail-preview views until patched (loss of template preview functionality but not core HR data), and filtering inbound mail-template bodies for '{{' / '{%' sequences that reference 'request.' or 'META' (blocking the traversal payloads while allowing benign placeholders, at the cost of false positives on legitimate templates). Because password hashes are directly readable, treat any post-1.0.0 deployment that was internet-reachable as potentially compromised: force password resets for affected users, rotate any secrets or tokens present in request.META, and review access logs for suspicious get-mail-preview traffic. The exploitation path mandates a valid session plus a CSRF token, so tightening single-sign-on session issuance does not remove the risk and should not be relied on as a mitigation.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Horilla is a Django-based HR/CRM application, and the flaw lives in the mail-preview rendering path: the get_mail_preview handlers in recruitment/views/actions.py and employee/not_in_out_dashboard.py passed the entire Django HttpRequest object into the template context and rendered a body the user controls. Because Django's template language resolves dotted attribute lookups (request.user.password, request.META, request.user.employee_get and similar relations) against arbitrary objects, an attacker who can place template expressions in the mail body or in the get_template 'word' parameter can walk from the request object into the ORM model behind request.user and read any attribute reachable that way. The CWE-94 (code injection) classification reflects that user-controlled input reaches template rendering, but Django's template sandbox does not evaluate Python code and blocks attribute access that raises exceptions, so the demonstrated primitive is data exfiltration, not remote code execution - a distinction the exploit tags overstate. The upstream fix is instructive: base/methods.py adds sanitize_mail_template_placeholders(), which strips all {% %} tags and removes any {{ }} expression not present in the MailTemplateForm placeholder allowlist (normalizing whitespace so '{{ instance . get_full_name }}' cannot bypass it), plus build_safe_template_request(), which keeps a 'request' name in the context but replaces it with a SimpleNamespace exposing only method, path, and a safe user proxy limited to id, username, is_authenticated, is_staff, and is_superuser. The recruitment view additionally gained a permission_required('recruitment.view_candidate') decorator and a queryset filter restricting candidate lookups to records the requesting employee manages.
Know when Django gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Network-reachable mail-preview endpoint needs an authenticated session (PR:L) with no user interaction; template traversal leaks password hashes/PII (C:H) but cannot modify or disrupt (I:N/A:N).
Primary rating from Vendor (github).
CVSS VectorVendor: github
Lifecycle Timeline
1DescriptionCVE.org
Horilla is an HR and CRM software. From 1.0.0 until 1.6.0 and 2.0.0, the get_mail_preview handlers in recruitment/views/actions.py and employee/not_in_out_dashboard.py render a user-controlled body at /recruitment/get-mail-preview/ and /employee/get-employee-mail-preview with the full request object in the Django template context. An authenticated user with a valid CSRF token can use template attribute traversal to read request.user.password, request.META, and related-user attributes, exposing password hashes, personal data, and server request metadata. Django template restrictions prevent arbitrary code execution through this primitive, so the demonstrated impact is information disclosure and possible offline password cracking or account compromise. This issue is fixed in versions 1.6.0 and 2.0.0.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Cross-Site Request Forgery exploits the automatic credential inclusion behavior of web browsers.
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
Code injection occurs when an application accepts user input and passes it directly into a language interpreter or evaluator without proper sanitization.
The package python/cpython from 0 and before 3.6.13, from 3.7.0 and before 3.7.10, from 3.8.0 and before 3.8.8, from 3.9
In Django 1.10.x before 1.10.8 and 1.11.x before 1.11.5, HTML autoescaping was disabled in a portion of the template for
An issue was discovered in Django 3.2 before 3.2.14 and 4.0 before 4.0.6. Rated critical severity (CVSS 9.8), this vulne
Django 3.1.x before 3.1.13 and 3.2.x before 3.2.5 allows QuerySet.order_by SQL injection if order_by is untrusted input
Django before 1.11.27, 2.x before 2.2.9, and 3.x before 3.0.1 allows account takeover. Rated critical severity (CVSS 9.8
An authentication/authorization bypass in the djust Python live-view framework (versions prior to 1.0.7) lets unauthenti
Unauthenticated arbitrary Python module import in djust before 1.0.7 lets any client that can reach the WebSocket or SSE
Django 1.11 before 1.11.29, 2.2 before 2.2.11, and 3.0 before 3.0.4 allows SQL Injection if untrusted data is used as a
Cross-site scripting (XSS) vulnerability in the dismissChangeRelatedObjectPopup function in contrib/admin/static/admin/j
Forged content modification in django-page-cms through 2.0.13 lets unauthenticated remote attackers exploit five CSRF-ex
Cross-site request forgery in djust's Server-Sent-Events transport affects all versions prior to 1.0.7 and allows a cros
Unauthenticated remote attackers can read live Django view and session state and invoke server-side handlers through dju
EUVD-2026-87363
NVD
CVE.org
EPSS
Vulnrichment
GitHub
VulDB
Exploit-DB