CVE-2026-63432
Executive Summary
CVE-2026-63432 is a server-side template injection / information-disclosure flaw in Horilla, an open-source HR and CRM application. The get_mail_preview handlers in recruitment/views/actions.py and employee/not_in_out_dashboard.py render a user-controlled body at the /recruitment/get-mail-preview/ and /employee/get-employee-mail-preview endpoints while exposing the full Django request object in the template context. Any authenticated user holding a valid CSRF token can abuse Django template attribute traversal to read request.user.password, request.META, and related-user attributes — exposing password hashes, personal data, and server request metadata. The issue is fixed in versions 1.6.0 and 2.0.0; deployments on 1.0.0 through pre-1.6.0, and 2.0.0 prior to the fix, remain exposed.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Horilla is a Django-based HR and CRM platform. The vulnerable code resides in two separate view modules:
recruitment/views/actions.py— theget_mail_previewhandler, reachable at/recruitment/get-mail-preview/employee/not_in_out_dashboard.py— the employee-facing preview handler, reachable at/employee/get-employee-mail-preview
Both handlers accept a user-controlled body value and render it as a Django template. Critically, the rendering context includes the full request object (request). Django's template engine permits attribute lookup and method-style traversal on objects placed in the context via dot notation (e.g., {{ request.user }}, {{ request.META }}). Because the user controls the template source and the request object is in scope, the attacker can walk object attributes and read sensitive values that were never intended to be template-accessible.
The demonstrated primitive yields access to:
request.user.password— the stored password hash of the authenticated user (and, via related-user attribute traversal, potentially other users' hashes).request.META— the full server-side request metadata dictionary (headers, environment-derived values, client IP, host, etc.).- Related-user attributes — any object reachable from
request.userthrough Django ORM relationships.
The CWE classification is CWE-94 (Improper Control of Generation of Code — "Code Injection") because the underlying defect is the unsafe rendering of user-controlled input as a server-side template. However, the NVD description explicitly states that Django template restrictions prevent arbitrary code execution through this primitive. There is therefore no RCE: the practical impact is bounded to information disclosure.
Key constraints on exploitation, all confirmed by the description:
- The attacker must be authenticated (CVSS
PR:L). - A valid CSRF token is required — the endpoints are CSRF-protected, so the attack is a direct authenticated request, not a cross-site forgery.
- No user interaction beyond the attacker's own actions (
UI:N). - Impact is confined to confidentiality (
C:H); no integrity or availability impact (I:N/A:N), and scope is unchanged (S:U).
No public PoC, no Nuclei template, and no exploit code are available for this CVE. The analysis below is derived strictly from the NVD description and the vulnerability class.
Exploitation Scenarios
Note: No public PoC is available; the attack chain is inferred from the vulnerability class and the NVD description. Only endpoint names, file paths, parameter attributes (body, request.user.password, request.META), and behaviors explicitly named in the description are used below.
1) Reconnaissance / target identification. The attacker identifies an internet- or intranet-exposed Horilla instance running a vulnerable version (1.0.0 through pre-1.6.0, or the affected 2.0.0 build). Fingerprinting is straightforward because the application exposes its own paths: /recruitment/get-mail-preview/ and /employee/get-employee-mail-preview. Access to either endpoint requires an authenticated session, so the attacker must first obtain any valid low-privilege account — a self-registered user, a compromised credential, or a provisioned contractor/employee account.
2) Triggering the flaw. Using the authenticated session, the attacker issues a request to /recruitment/get-mail-preview/ (or /employee/get-employee-mail-preview) that supplies their own session cookie and a valid CSRF token, and passes malicious template content as the user-controlled body value.
3) Payload / execution at the vulnerability-class level. The attacker submits Django template markup in the body field that performs attribute traversal on the request object that the view places in the template context. For example, template expressions referencing request.user.password cause the rendered output to include the password hash in the HTTP response. Similarly, request.META (and attributes reachable through request.user relationships) can be enumerated to dump server request metadata and related-user fields. Because the view echoes the rendered result back to the requester, the attacker simply reads the values from the response body. The description notes that Django's template sandbox restrictions block escalation to arbitrary code execution — the attacker cannot run shell commands or import modules through this path.
4) Post-exploitation impact. The attacker obtains password hashes and personal data. Matched against offline cracking (dictionary/brute-force against the captured hashes), this can yield cleartext credentials and lead to account compromise and lateral movement into HR/CRM records. request.META leakage also aids further reconnaissance (internal hostnames, header values, environment context) and can facilitate follow-on attacks against the same or adjacent systems.
Impact Assessment
- Confidentiality: High (
C:H). Password hashes and other sensitive user attributes can be read directly. Password hashes are high-value because they enable offline cracking, independent of any further server compromise. - Integrity: None (
I:N) / Availability: None (A:N). The flaw is read-only; no data modification or denial-of-service is described. - Scope: Unchanged (
S:U). Impact remains within the Horilla application's security authority. - Attack Vector: Network (
AV:N), Complexity: Low (AC:L), Privileges Required: Low (PR:L), User Interaction: None (UI:N). CVSS 3.1 base score 6.5 (Medium).
Blast radius. Every Horilla deployment on an affected version that permits user self-registration or has any low-privilege account is in scope. Because the read primitive targets request.user and related-user attributes, the more accounts an attacker can authenticate as, the broader the set of hashes/personal data they can harvest. Multi-tenant or large-enterprise HR deployments face disproportionate exposure given the volume of PII they hold (employee records, CRM contacts). Leaked request.META broadens the reconnaissance surface for chained attacks against the hosting infrastructure.
Business impact. Regulatory exposure (PII/password-hash disclosure), credential-compromise risk, and potential downstream account takeover. No ransomware or availability impact is associated with this CVE.
Detection Guidance
Sigma Rule
title: Horilla get_mail_preview Template Attribute Traversal
id: 3f9c2b71-8a4e-4d13-b6c9-7e2a1d0f5b44
status: experimental
description: Detects exploitation of CVE-2026-63432 via Django template attribute traversal on Horilla mail preview endpoints.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-63432
author: valtersit.com Threat Intelligence
date: 2026-01-01
logsource:
category: webserver
detection:
selection_endpoint:
cs-uri-stem|contains:
- '/recruitment/get-mail-preview/'
- '/employee/get-employee-mail-preview'
selection_payload:
cs-uri-query|contains:
- 'request.user.password'
- 'request.META'
- '{{'
- 'request.user'
condition: selection_endpoint and selection_payload
fields:
- c-ip
- cs-uri-stem
- cs-uri-query
- cs-username
level: high
falsepositives:
- Legitimate template editing by administrators (rare; investigate)
YARA Rule
rule CVE_2026_63432_Horilla_Template_Traversal
{
meta:
description = "Detects Django template attribute-traversal payloads targeting Horilla mail preview handlers (CVE-2026-63432)"
author = "valtersit.com"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-63432"
date = "2026-01-01"
severity = "high"
strings:
$ep1 = "/recruitment/get-mail-preview/"
$ep2 = "/employee/get-employee-mail-preview"
$tpl1 = "request.user.password"
$tpl2 = "request.META"
$tpl3 = "{{ request"
$tpl4 = "{{request"
condition:
(any of ($ep1, $ep2)) and (any of ($tpl1, $tpl2, $tpl3, $tpl4))
}
Suricata IDS Rule
alert http any any -> any any ( \
msg:"CVE-2026-63432 Horilla get_mail_preview Django template attribute traversal attempt"; \
flow:established,to_server; \
http.uri; content:"/recruitment/get-mail-preview/"; nocase; \
http.uri; content:"request.user.password"; nocase; \
reference:cve,CVE-2026-63432; \
classtype:attempted-recon; \
sid:2026634321; rev:1; )
alert http any any -> any any ( \
msg:"CVE-2026-63432 Horilla employee mail preview template traversal attempt"; \
flow:established,to_server; \
http.uri; content:"/employee/get-employee-mail-preview"; nocase; \
http.uri; content:"request.META"; nocase; \
reference:cve,CVE-2026-63432; \
classtype:attempted-recon; \
sid:2026634322; rev:1; )
Elastic Detection
sequence by source.ip, user.name with maxspan=1m
[ url.path : ("/recruitment/get-mail-preview/" or "/employee/get-employee-mail-preview") ]
[ url.query : ("*request.user.password*" or "*request.META*" or "*{{*") ]
Splunk SPL Query
index=web sourcetype=access_combined OR sourcetype=horilla
(uri_path="/recruitment/get-mail-preview/" OR uri_path="/employee/get-employee-mail-preview")
(uri_query="*request.user.password*" OR uri_query="*request.META*" OR uri_query="*%7B%7B*" OR uri_query="*{{*" OR body="*request.user*")
| stats count min(_time) as first_seen max(_time) as last_seen values(uri_query) as payloads by src_ip uri_path user
| where count >= 1
Wazuh OSSEC Rule
<group name="horilla,web,cve-2026-63432,">
<rule id="2026634" level="12">
<decoded_as>web-accesslog</decoded_as>
<url>/recruitment/get-mail-preview/|/employee/get-employee-mail-preview</url>
<regex type="pcre2">request\.user\.password|request\.META|\{\{</regex>
<description>CVE-2026-63432: Horilla Django template attribute traversal attempt (template injection info disclosure).</description>
<mitre>
<id>T1190</id>
<id>T1552.001</id>
</mitre>
<group>attack,information_disclosure,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). The NVD description states the issue is fixed in versions 1.6.0 and 2.0.0, but no vendor advisory URL, commit reference, or release artifact was provided by tracked sources. Treat the following as compensating guidance until a verifiable vendor patch is confirmed.
1) Immediate mitigations (no patch required):
- Restrict access to
/recruitment/get-mail-preview/and/employee/get-employee-mail-previewat the reverse proxy / WAF layer to trusted networks and authenticated administrative roles only. - Remove the
requestobject from the Django template rendering context for theget_mail_previewhandlers inrecruitment/views/actions.pyandemployee/not_in_out_dashboard.py— pass only the minimum data required (e.g., a pre-rendered body string) rather than the full request object. - Treat the user-supplied
bodyas data, not template source: render it with an auto-escaping context, or disable server-side template interpretation of user input entirely. - Rotate all user credentials and session tokens if exploitation is suspected; the disclosure enables offline hash cracking, so credential resets are required rather than optional.
- Enforce MFA on all Horilla accounts and reduce the number of low-privilege/self-registered accounts that can reach the affected endpoints.
2) Patch / upgrade steps:
- Upgrade Horilla to 1.6.0 (for the 1.x line) or 2.0.0 (for the 2.x line) or later. Verify the fix against a staging instance before production rollout.
- Because patch confidence is 0/4, independently confirm the fix: after upgrade, re-issue a template payload against both endpoints and confirm
request.user.password/request.METAare no longer rendered. - Monitor the project's release channel and NVD entry for an official advisory and stable CVE-specific reference.
3) Long-term hardening:
- Adopt a policy that user-supplied content is never rendered as a server-side template; enforce template sandboxing and context minimization during code review.
- Add SAST/CI checks for Django template rendering of user input and for full request objects placed in template contexts.
- Deploy WAF rules for the two affected endpoints and the signature patterns above.
- Apply the detection rules in this report across web access logs, and alert on any authenticated access to the mail-preview endpoints containing template syntax.
References
- NVD — CVE-2026-63432: https://nvd.nist.gov/vuln/detail/CVE-2026-63432
- Horilla project (vendor source): https://github.com/horilla-opensource/horilla — consult release tags for the 1.6.0 / 2.0.0 fixes referenced in the CVE description
- CWE-94 — Improper Control of Generation of Code ("Code Injection"): https://cwe.mitre.org/data/definitions/94.html
- MITRE ATT&CK — T1190 Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/
- CISA Known Exploited Vulnerabilities Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog — CVE-2026-63432 is not listed as of this report.
Threat actor campaigns / exploit-in-the-wild: none known. No public PoC, no Nuclei template, no exploit code, and no EPSS score are available. FIRST.org has not yet scored this CVE, and no campaign has been attributed to it. Monitor NVD and CISA KEV for changes.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.