☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Horilla logo [ WEBSITE ] [ VENDOR STATS ]
SOON 🐛 CWE-352
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-86066

CVE-2026-86066 Cross-Site Request Forgery in Horilla
📅 PUBLISHED: 2026-09-25 00:00 UTC 🔄 UPDATED: 2026-09-27 00:04 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.20%
👁️
0.20% probability
5.0× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1204.001
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
Country: Global License: Open Source
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
SOON
PENDING NVD
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-86066 is a Cross-Site Request Forgery (CSRF) vulnerability in Horilla, an open-source HR and CRM application, affecting all versions prior to 2.0.0. The approve_validate_attendance_request endpoint at /attendance/approve-validate-attendance-request/ performs a state-changing attendance approval via HTTP GET, bypassing Django's CSRF protections, which apply only to unsafe methods. An unauthenticated attacker can lure a logged-in manager holding attendance.change_attendance permission into a crafted request that silently approves attendance records under the victim's session and identity.

The impact is integrity-focused: unauthorized, fraudulent approval of attendance requests, with the approval misattributed to the victim manager in the audit trail. No public proof-of-concept, nuclei template, or exploit code is currently available, and the vulnerability is not listed in CISA KEV.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Technical Analysis

The core defect is a violation of two foundational web security principles combined: the use of HTTP GET for a state-changing operation, and the consequence that Django's built-in CSRF middleware does not enforce token validation on GET requests.

Per the NVD description, the function approve_validate_attendance_request at the URL path /attendance/approve-validate-attendance-request/ mutates several persistence-layer fields — specifically attendance_validated, is_validate_request_approved, approved_by, and "related pending-request state" — and then calls attendance.save() to commit those changes to the database. Because this state transition is reachable through an HTTP GET request, Django's CSRF framework, which by design validates only unsafe methods (POST, PUT, PATCH, DELETE), provides no protection. The attacker therefore does not need to obtain or predict a CSRF token.

A secondary and critical facilitator is the session cookie's SameSite attribute. The description states the victim's session cookie is SameSite=Lax. Under the Lax policy, browsers do not attach cookies to most cross-site requests, but they do attach them to top-level navigations performed with safe methods such as GET. This means a simple top-level GET navigation initiated from an attacker-controlled page will carry the victim manager's session cookie to the Horilla origin, authenticating the forged request transparently.

The attacker is unauthenticated — they need no Horilla account and no knowledge of the victim's credentials. The only privilege requirement is that the victim be a logged-in manager who possesses the attendance.change_attendance permission. The description explicitly notes that the request "carries the manager's SameSite=Lax session cookie," and the resulting approval is "attributed to the victim in the audit trail," because the application records approved_by based on the authenticated session rather than any independent authorization check at the request layer.

The attack surface is the attendance approval workflow of the Horilla HR module. There is no injection, memory-corruption, or authentication-bypass primitive here; the vulnerability class is purely authorization-binding failure (state change without CSRF token enforcement). No further code-level details (view decorator behavior, URL routing specifics beyond the one provided path, or models beyond the named fields) are available from the supplied data, and none should be assumed.


Exploitation Scenarios

No public PoC is available; the attack chain below is inferred strictly from the described vulnerability class (CSRF via state-changing GET) and the technical facts provided.

  1. Reconnaissance / target identification. The attacker identifies Horilla instances prior to 2.0.0 exposed to users, for example via a web search or by fingerprinting pages that render Horilla's HR/CRM interface. The attacker only needs to confirm the instance is running a vulnerable version and uses the /attendance/ module.

  2. Victim condition establishment. The attacker identifies or waits for a scenario where a manager holding the attendance.change_attendance permission is logged in. This is a normal operational state for HR/line managers who routinely approve attendance. The SameSite=Lax session cookie is already present in the victim's browser.

  3. Triggering the flaw class. The attacker constructs a request to the vulnerable GET endpoint https://<horilla-host>/attendance/approve-validate-attendance-request/ with whatever parameters the application expects to identify the attendance record(s) to approve. Because the state change is served over GET, no CSRF token is generated or checked. The attacker embeds this URL into a top-level navigation — for example an <a href> link, a page redirect, or an image/link that the victim clicks — delivered by email, chat, or a malicious site.

  4. Session cookie carriage and execution. When the victim performs the top-level navigation, the browser applies the SameSite=Lax policy and attaches the manager's session cookie to the GET request. Horilla authenticates the request as the victim manager, executes approve_validate_attendance_request, sets attendance_validated and is_validate_request_approved, records the victim in approved_by, updates the related pending-request state, and calls attendance.save(). The approval is committed without the victim's knowledge.

  5. Post-exploitation impact. The attacker has achieved unauthorized approval of attendance records with no direct account access and no malware. Because approved_by stores the victim's identity, the fraudulent approval is attributed to the victim manager — enabling loss of audit integrity, potential internal-fraud scenarios (e.g., approving manipulated or unauthorized attendance), and reputational or disciplinary exposure for the falsely-attributed manager.


Impact Assessment

CVE-2026-86066 is an integrity-only vulnerability. No confidentiality impact (attendance data is not disclosed to the attacker) and no availability impact (the application continues to function) are described. The primary impacts are:

  • Audit-trail corruption. Because approved_by is populated with the victim's identity, the record of who authorized the attendance is factually false. This compromises the evidentiary value of attendance and payroll-adjacent records.
  • Transactional fraud enablement. Unauthorized approvals may directly affect worked-hours records, which in mature HR deployments feed payroll, overtime, and compliance calculations. The blast radius is therefore the downstream systems and processes consuming approved attendance — not the Horilla database alone.
  • Reputational and compliance exposure. Falsely attributed approvals can implicate innocent managers in disciplinary investigations, undermine labor-law compliance evidence, and complicate HR dispute resolution.
  • Blast radius. Limited to organizations running Horilla < 2.0.0 with the attendance approval workflow in active use. Impact scales with the number of managers holding attendance.change_attendance and the number of pending approval requests at any time.

CVSS mapping. The vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N reflects: network reachable (AV:N), no special conditions (AC:L), attacker unauthenticated (PR:N), victim must perform a user action such as a navigation (UI:R), scope unchanged (S:U), no confidentiality loss (C:N), partial/low integrity loss (I:L, limited to approval state), and no availability loss (A:N). Note: no official CVSS score was provided in the source data, so no numeric score is asserted.


Detection Guidance

Sigma Rule

title: Horilla Attendance Approval via GET CSRF (CVE-2026-86066)
id: 3d9c1f2a-77b4-4e6a-9c1e-9horilla86066
status: experimental
description: Detects GET requests to the Horilla attendance approval endpoint, which performs a state change and is exploitable for CSRF prior to Horilla 2.0.0.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-86066
author: valtersit.com Threat Intelligence
logsource:
  category: webserver
  product: generic
detection:
  selection_method:
    cs-method: 'GET'
  selection_uri:
    cs-uri-stem|contains: '/attendance/approve-validate-attendance-request/'
  condition: selection_method and selection_uri
falsepositives:
  - Legitimate application UI calls if Horilla front-end uses GET internally (verify against 2.0.0 behavior)
level: medium

YARA Rule

rule CVE_2026_86066_Horilla_CSRF_URI
{
    meta:
        description = "Detects the vulnerable Horilla attendance approval URI in logs, traffic captures, or proxied artifacts (CVE-2026-86066)"
        author = "valtersit.com Threat Intelligence"
        reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-86066"
        date = "2026-01-01"
        severity = "medium"

    strings:
        $uri = "/attendance/approve-validate-attendance-request/" ascii wide nocase
        $f1  = "attendance_validated" ascii wide
        $f2  = "is_validate_request_approved" ascii wide
        $f3  = "approved_by" ascii wide

    condition:
        $uri or (2 of ($f*))
}

Suricata IDS Rule

alert http any any -> any any (msg:"CVE-2026-86066 Horilla Attendance CSRF Approval via GET"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"/attendance/approve-validate-attendance-request/"; nocase; classtype:web-application-attack; reference:cve,2026-86066; sid:202686066; rev:1;)

Elastic Detection

sequence by source.ip with maxspan=5m
  [network where network.protocol == "http" and http.request.method == "GET" and
     url.path : "/attendance/approve-validate-attendance-request/*"]

Note: In environments where Horilla is fronted by a reverse proxy, adapt the EQL to target the proxy access-log index and the url.path field accordingly. A single matching event followed by a subsequent state-change confirmation on the same attendance record can corroborate exploitation.

Splunk SPL Query

index=web OR index=proxy
| search method=GET uri_path="/attendance/approve-validate-attendance-request/*"
| stats count min(_time) as first_seen max(_time) as last_seen by src_ip, uri_path, user_agent, referer
| where count >= 1
| sort - count

To highlight cross-site referrers (a strong CSRF signal), add:

| eval suspicious=if(match(referer,"(?i)^https?://(?!<your-horilla-domain>)"),1,0)
| where suspicious=1

Wazuh OSSEC Rule

<group name="web,horilla,cve-2026-86066,">
  <rule id="100860" level="10">
    <decoded_as>web-accesslog</decoded_as>
    <if_sid>31100</if_sid>
    <url>/attendance/approve-validate-attendance-request/</url>
    <method>GET</method>
    <description>CVE-2026-86066: Horilla attendance approval requested via GET (CSRF attempt)</description>
    <mitre>
      <id>T1204.001</id>
    </mitre>
    <group>cve_2026_86066,csrf,web_attack,</group>
  </rule>

  <rule id="100861" level="12">
    <if_sid>100860</if_sid>
    <referer>^https?://</referer>
    <description>CVE-2026-86066: Horilla attendance GET approval with external referrer (probable CSRF)</description>
    <group>cve_2026_86066,csrf,high_confidence,</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 version 2.0.0, but no tracked source has supplied a patch URL, commit hash, or vendor advisory link. The guidance below reflects that gap.

  1. Immediate mitigations (compensating controls).

    • Restrict network access to the Horilla web interface to trusted internal ranges or a VPN, reducing the ability of external attacker pages to reach victim managers in a session-carrying top-level navigation.
    • At the reverse proxy / WAF layer, block or challenge GET requests to /attendance/approve-validate-attendance-request/ that carry an external or absent Referer/Origin header. Note that some browsers suppress Referer; do not rely on it as a sole control.
    • Consider short session timeouts and re-authentication for approval workflows to narrow the exploitation window, though this does not close it.
    • Educate managers with attendance.change_attendance not to click unsolicited links while logged into Horilla.
  2. Patch / upgrade steps.

    • Upgrade Horilla to version 2.0.0 or later, the version identified as containing the fix. Validate by reviewing the release notes and confirming the approval action no longer executes via GET and requires a CSRF token.
    • Because no tracked patch reference exists, verify the fix directly: after upgrade, confirm the endpoint rejects state changes on GET and that the approval UI issues a POST (or equivalent) with a valid CSRF token.
  3. Long-term hardening.

    • Enforce Django-native CSRF protection on all state-changing views, and never perform mutations on GET. Adopt django.views.decorators.http.require_POST (or equivalent method restriction) for approval and similar workflows.
    • Set session cookies to SameSite=Strict where feasible to eliminate the top-level-navigation cookie carriage that Lax permits.
    • Add Origin/Referer validation middleware for privileged, state-changing endpoints as defense in depth.
    • Codify REST/HTTP semantics in code review: GET must be idempotent and side-effect free.

References

  1. NVD — CVE-2026-86066: https://nvd.nist.gov/vuln/detail/CVE-2026-86066
  2. Horilla project (vendor/product source): Horilla HR and CRM software — consult the project's official release channel for the 2.0.0 release notes confirming the fix.
  3. CWE-352 — Cross-Site Request Forgery: https://cwe.mitre.org/data/definitions/352.html
  4. OWASP — Cross-Site Request Forgery Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
  5. FIRST — EPSS (not yet scored at time of writing): https://www.first.org/epss/

Exploit-in-the-wild / threat actor evidence: None observed. CVE-2026-86066 is not listed in CISA KEV, no public proof-of-concept, nuclei template, or exploit code is available, and no named threat actor campaigns have been associated with this CVE in the supplied intelligence data. The attack is a straightforward, low-sophistication CSRF technique typical of opportunistic, targeted, or insider-adjacent abuse rather than a nation-state or ransomware TTP.

👁️ SHODAN DORKS (THREAT HUNTING)

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.

product:"Horilla"
title:"Horilla"
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-86066/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.