CVE-2026-109320
Executive Summary
CVE-2026-109320 is an improper session validation vulnerability in the Grav API plugin (grav-plugin-api) before version 1.0.36. Because SessionAuthenticator does not enforce account state, an account that has been disabled by an operator retains working API access as long as an already-authorized browser session or "remember-me" session remains valid. This defeats operator revocation for deployments that expose the Grav API plugin to authenticated users, allowing a disabled (for example, terminated or suspended) account to continue calling API endpoints until the session expires. The flaw is rated CVSS 5.4 (Medium) and has no public PoC, exploit code, or Nuclei template available at the time of writing.
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
The affected component is the Grav API plugin (grav-plugin-api), a plugin for the Grav flat-file CMS that exposes API endpoints for authenticated clients. The vulnerability is rooted in session handling logic: the SessionAuthenticator component does not enforce account state (enabled vs. disabled) when validating an existing session.
CWE-613 ("Insufficient Session Expiration") is the assigned weakness. In practical terms, the defect is a failure of authorization-state re-checking rather than a cryptographic failure. Two authentication paths are explicitly named in the source description as being impacted:
- An already authorized browser session.
- A "remember-me" session.
The attack surface is any API endpoint that accepts session-based authentication from SessionAuthenticator. Because the component validates the integrity/validity of a session but not the current account state, a revocation event (disabling the account) does not cascade to existing sessions.
Key technical characteristics derivable from the available data:
- Preconditions: The attacker must hold a session that was authorized before the account was disabled. This is why
PR:L(Low privileges) andUI:N(No user interaction) are appropriate — no new credential theft or user interaction is required; possession of the pre-existing session token is sufficient. - Trigger: Continued use of a still-valid browser or remember-me session against API endpoints after the account is disabled.
- Duration of exposure: The window persists "until expiry" of the session — i.e., the maximum time-to-live of a browser session or the remember-me token. The description does not state a specific expiry duration, so no fixed window can be asserted.
- Integrity/Confidentiality impact (C:L/I:L): Scoped low — a disabled user can read and potentially modify data reachable through the API paths they were previously authorized for. There is no evidence of privilege escalation or horizontal movement beyond the disabled account's prior authorization.
- No Availability impact (A:N): The exploit does not degrade service availability.
The description does not provide function signatures, endpoint paths, token formats, or configuration keys beyond SessionAuthenticator and the plugin name, so no further implementation-level claims are made here.
The patch confidence is scored 0/4 (UNPATCHED): no vendor advisory, commit, or version-tagged fix has been tracked from any source, despite the affected-version boundary (< 1.0.36) being stated.
Exploitation Scenarios
No public PoC is available; the attack chain below is inferred from the vulnerability class (CWE-613, insufficient session expiration).
Reconnaissance / target identification. The attacker identifies a Grav instance running the API plugin (
grav-plugin-api) at a version below 1.0.36 and confirms that session-based (browser or remember-me) authentication is accepted by the API. Reconnaissance is achievable from public fingerprinting (e.g., Shodan dorks for Grav and the API plugin), since no authentication is needed to identify the product.Triggering the flaw class. The attacker holds a legitimate session that was authorized while the account was in an enabled state. The operator later disables the account (termination, suspension, incident response). On subsequent API calls, the credential provided is the still-valid session token — either the browser session cookie or the remember-me artifact.
SessionAuthenticatorvalidates the session but does not re-check whether the underlying account is currently enabled, so the request is accepted.Execution method (vulnerability-class level). The attacker replays the existing session against API endpoints the account was previously entitled to. No exploit payload, memory corruption, or injection is required; the "exploit" is the reuse of a valid-but-stale authorization artifact. Because the description does not enumerate specific endpoint paths, no endpoint-specific payload is asserted here.
Post-exploitation impact. The disabled user retains read (and potential write) access to data and operations exposed through the API for as long as the session remains valid. This defeats operator revocation, meaning an offboarded or suspended user retains data access until session/token expiry. There is no evidence of lateral movement, code execution, or elevation beyond the account's prior scope (consistent with
C:L/I:L/A:N).
Impact Assessment
Business impact centers on failed revocation and the resulting persistence of access. For organizations that use Grav's API plugin with session-based authentication, a disabled account — for example, a departing contractor, a terminated employee, or an account suspended during an investigation — can continue to interact with API endpoints until its session or remember-me token expires. This undermines access-control governance and offboarding procedures.
CVSS v3.1 assessment (reproduced from the supplied vector, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N = base 5.4, Medium):
- AV:N (Network) — the API is reachable over the network.
- AC:L (Low) — exploitation requires no special conditions beyond a valid pre-existing session.
- PR:L (Low) — the attacker must already possess a session belonging to a (formerly enabled) low-privilege account.
- UI:N (None) — no victim interaction is required.
- S:U (Unchanged) — impact remains within the same security authority.
- C:L / I:L (Low) — limited confidentiality and integrity impact, bounded by the account's prior entitlements.
- A:N (None) — no availability impact.
Blast radius: Scoped to accounts that (a) had an active browser or remember-me session and (b) were subsequently disabled, on deployments running grav-plugin-api < 1.0.36. The scope is bounded: this is not an unauthenticated takeover, and it does not grant privileges beyond what the disabled account previously held. The principal risk is retention of access post-revocation.
CISA KEV status: NOT listed. EPSS: not yet scored by FIRST.org (no value fabricated).
Detection Guidance
Detection strategy: correlate operator-initiated account-disable events with subsequent successful API activity attributable to the same account/session. Because no public PoC, exploit code, or Nuclei template exists, rules should focus on behavioral anomaly — API use after disable — rather than a known payload signature.
Sigma Rule
title: Grav API Session Use After Account Disable (CVE-2026-109320)
id: 3b7c9e1a-1f42-4d8a-9c21-0e5d6a7f2b10
status: experimental
description: Detects API access by a Grav account after the account was disabled, consistent with improper session validation in grav-plugin-api before 1.0.36.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-109320
author: valtersit.com
date: 2026/01/01
logsource:
product: grav
service: api
detection:
selection_disable:
action:
- 'user_disabled'
- 'account_disabled'
- 'user_suspended'
selection_api:
event_type:
- 'api_request'
- 'api_access'
outcome: 'success'
condition: selection_disable or (selection_api)
timeframe: 24h
fields:
- user
- session_id
- src_ip
- endpoint
falsepositives:
- Administrative actions immediately following a disable event
level: medium
tags:
- attack.t1078
- cve.2026-109320
YARA Rule
rule CVE_2026_109320_Grav_API_SessionAuthenticator
{
meta:
description = "Detects grav-plugin-api SessionAuthenticator artifacts lacking account-state enforcement (CVE-2026-109320)"
author = "valtersit.com"
date = "2026-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-109320"
cve = "CVE-2026-109320"
strings:
$plugin = "grav-plugin-api" ascii nocase
$auth = "SessionAuthenticator" ascii
$rm = "remember" ascii nocase
condition:
$plugin and $auth
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-109320 Grav API Possible Session Use After Disable"; flow:established,to_server; http.header; content:"Cookie"; nocase; http.cookie; content:"grav" nocase; reference:cve,2026-109320; classtype:attempted-user; sid:2026109320; rev:1;)
Elastic Detection
sequence by user.name with maxspan=24h
[ any where event.action in ("user_disabled", "account_disabled", "user_suspended") ]
[ any where event.category == "web" and event.action in ("api_request", "api_access") and http.response.status_code < 400 ]
Splunk SPL Query
index=grav OR index=web sourcetype=grav:api
| eval acct=coalesce(user, account, username)
| where (action IN ("user_disabled","account_disabled","user_suspended")) OR (event_type IN ("api_request","api_access") AND status<400)
| stats values(action) as actions, values(endpoint) as endpoints, min(_time) as first, max(_time) as last by acct
| where mvfind(actions,"disable") >= 0 AND mvcount(endpoints) > 0
| convert ctime(first) ctime(last)
Wazuh OSSEC Rule
<group name="grav,api,cve-2026-109320">
<rule id="109320" level="10">
<decoded_as>json</decoded_as>
<field name="event_type">api_request|api_access</field>
<field name="action">user_disabled|account_disabled|user_suspended</field>
<description>CVE-2026-109320: Grav API activity associated with a disabled account (possible session validation bypass)</description>
<mitre>
<id>T1078</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 — UNPATCHED. No patch evidence from any tracked source. Vendor fix: N/A. Workarounds: N/A.
Immediate mitigations
- Invalidate all active sessions and remember-me tokens for any account that is disabled, using the platform's session-management capabilities where available. Treat account disablement as requiring an explicit session reset step.
- Where possible, reduce session and remember-me token lifetimes for API-authenticated accounts to shrink the exposure window.
- Restrict network access to the Grav API plugin to trusted networks / VPN segments so that stale sessions cannot be replayed from untrusted origins.
- Increase monitoring of API access attributable to disabled accounts and alert on any post-disable success (see Detection Guidance).
Patch / upgrade steps
- The affected-version boundary is
grav-plugin-api < 1.0.36. Upgradegrav-plugin-apito 1.0.36 or later once a verified vendor release addressing the account-state check inSessionAuthenticatoris available. At the time of writing, no patch artifact is confirmed from tracked sources; validate the changelog and release signatures before deployment. - After upgrading, rotate any secrets and force re-authentication of all API sessions.
- The affected-version boundary is
Long-term hardening
- Enforce account-state re-validation on every authenticated request, not only at session creation, in custom plugins and API-gateway layers.
- Implement centralized revocation: disabling an account should immediately terminate its sessions and revoke remember-me tokens.
- Adopt short-lived tokens with refresh, and log disable events with correlation IDs to enable reliable detection.
- Monitor vendor advisories for
grav-plugin-apiand subscribe to the CVE record for updated patch status.
References
- NVD — CVE-2026-109320: https://nvd.nist.gov/vuln/detail/CVE-2026-109320
- MITRE CWE-613 — Insufficient Session Expiration: https://cwe.mitre.org/data/definitions/613.html
- MITRE ATT&CK T1078 — Valid Accounts: https://attack.mitre.org/techniques/T1078/
- Grav official project / plugin repository (verify vendor release notes for grav-plugin-api 1.0.36): https://getgrav.org/
- CISA KEV catalog (verify current listing status; CVE-2026-109320 was NOT listed at time of writing): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No known threat-actor campaigns or exploit-in-the-wild evidence were identified for CVE-2026-109320 at the time of writing (no PoC, no exploit code, no Nuclei template, not in CISA KEV).
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.