CVE-2026-72610
Executive Summary
CVE-2026-72610 is a stored SQL injection vulnerability in the Koha open-source Integrated Library System (ILS). An authenticated staff member holding the borrowers => edit_borrowers permission can plant a time-based SQL payload in a patron's lang field; the payload executes whenever an issue slip is printed for that patron, causing repeated, compounding denial-of-service delays in the staff client (CVSS 3.1 base score 4.3, low availability impact). Koha instances up to and including branches 24.11.17, 25.05.12, 25.11.06, and 26.05.01 are affected, and no official patch has been identified by any tracked source at this time.
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
Koha is a widely deployed web-based ILS used by public, academic, and special libraries to manage cataloguing, circulation, and patron accounts. The staff client exposes patron-management functions to authenticated library personnel, with granular sub-permissions such as borrowers => edit_borrowers controlling who may modify a patron record.
The vulnerability resides in the patron record's lang field — a short attribute normally used to store the patron's preferred language/locale code. Koha does not appear to apply an allowlist or input-validation policy to this field; the NVD description states that the field physically accommodates only 25 characters, which constrains the size of any payload an attacker can store.
The flaw is triggered at the application layer: the stored lang value is concatenated raw — unparameterized — into a subquery constructed inside Koha::AdditionalContents->search_for_display. This method is responsible for retrieving "additional contents" rows (e.g., news items and slip-news) for presentation. When an issue slip (the receipt generated at checkout) is printed for a patron whose lang value contains malicious SQL, the malformed value is interpolated into the SQL subquery and executed by the database engine.
Because the column is limited to 25 characters, the practical exploitation technique is a time-based blind payload — for example, a fragment invoking a database sleep function (the NVD description explicitly names timing attacks and notes that data extraction is "not practical"). The described behavior is consistent with SLEEP() style functions: the injected expression causes the database server to pause for a controllable interval. Attackers are able to tune the SLEEP value, and the resulting delay scales linearly both with that value and with the number of slip-news rows processed by the vulnerable subquery, producing a multiplication effect on every trigger.
The attack has persistence and compounding characteristics: once the payload is stored, it remains in the patron record indefinitely. Every subsequent issue-slip print for that patron re-executes the payload, so a single poisoned patron record produces an availability-impacting event on an ongoing basis until the record is manually cleaned. The CVSS vector reflects this: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L — network-accessible, low complexity, requiring valid low-privilege staff credentials, with no confidentiality or integrity impact and low availability impact. Notably, UI:N indicates no victim user interaction is required for the stored payload to fire in the CVSS model; in operational reality, another staff member printing the slip triggers it.
Attack surface: the Koha staff client, reachable over the network; an authenticated account with the edit_borrowers sub-permission. Exploitation is not possible from the unauthenticated Internet directly, but it is remotely triggerable once valid staff credentials are obtained (e.g., via credential theft, phishing, or a malicious insider with limited rights).
Exploitation Scenarios
No public PoC or exploit code has been identified, and the attack chain below is inferred strictly from the vulnerability class and the NVD description. The four stages are:
1) Reconnaissance and target identification. The attacker identifies a Koha staff-client endpoint reachable over the network (Shodan-style fingerprints commonly include Koha branding in HTTP titles and /cgi-bin/koha/ in URL paths). The attacker must obtain, or already possess, valid staff credentials with the borrowers => edit_borrowers permission. This is the principal access barrier — the account is low-privileged, but authenticated.
2) Flaw-class triggering. The attacker edits a patron record and populates the lang field with a time-based SQL injection payload rather than a legitimate language code. The payload must fit within the 25-character column limit, which drives payload design toward compact time-based primitives (e.g., sleep expressions) rather than data-exfiltrating UNION-based queries. The description explicitly rules out practical data extraction, so the payload's purpose is exclusively delay generation.
3) Payload execution mechanism. The malicious lang value is stored in the patron record. When any staff member prints an issue slip for the poisoned patron, Koha retrieves the value and concatenates it raw into a subquery constructed in Koha::AdditionalContents->search_for_display. The SQL fragment executes, invoking the time-based primitive and pausing the database engine. The delay scales linearly with the chosen sleep value and with the number of slip-news rows in the subquery, so even a 25-character payload can produce a substantial, compounded pause.
4) Post-exploitation impact. Each subsequent issue-slip print for the affected patron re-executes the storable payload, producing recurring delays. An attacker who poisons many patron records, or selects a high sleep value, can effectively render the circulation desk's checkout/slip-printing workflow non-functional — a targeted denial-of-service condition. Because the payload is persistent and survives session/session boundaries, remediation requires database-level cleanup of the affected patron records. No confidentiality breach (C:N) or data integrity impact (I:N) is possible under the described constraints.
Impact Assessment
- Confidentiality: None. The 25-character field limit and the timing-only nature of the injection make data extraction impractical, per the NVD description.
- Integrity: None. No database content can be altered or exfiltrated through this vector.
- Availability: Low, but persistent and repeatable. The stored payload converts a routine circulation operation (issue-slip printing) into a database pause. The linear scaling with slip-news rows can amplify a single payload into a multi-second stall, and the stored nature means every subsequent print re-triggers the delay. An attacker with access to edit many patron records can cause recurring, widespread disruption to circulation workflows.
- Affected systems: Koha installations in the 24.11.x, 25.05.x, 25.11.x, and 26.05.x maintenance branches (up to and including 24.11.17, 25.05.12, 25.11.06, and 26.05.01). Any instance exposing the staff client to authenticated users is in scope.
- Blast radius: The vulnerability is exploitable only by authenticated staff (or by an attacker who compromises such an account). The direct blast radius is the Koha instance's circulation/printing functionality. Downstream effects include degraded library operations, increased help-desk load, and potential cascading timeouts for other database-dependent staff-client operations.
- Exploit likelihood: EPSS score 0.00199 (10th percentile of exploited CVEs) indicates a very low probability of exploitation in the wild at the time of assessment. The CVE is not present in the CISA Known Exploited Vulnerabilities catalog, and no threat-actor campaigns or exploit-in-the-wild evidence have been reported. However, the low authentication barrier and the persistent nature of the stored payload make it attractive for insider abuse or low-skill harassment attacks.
Detection Guidance
Because CVE-2026-72610 is a stored injection, the network layer typically observes only the initial request that writes the malicious lang value; the damaging execution occurs later inside the application/database. Detection should therefore combine network-layer SQLi pattern matching (to catch the initial write), database slow-query monitoring (to catch the execution event), and log/audit review of patron records for anomalous lang values.
Sigma Rule
title: Koha CVE-2026-72610 Time-Based SQLi Payload in Patron Lang Field
id: c07e23f1-6c9a-4b2d-9e5a-0f8a1c2d3e4f
status: experimental
description: Detects HTTP requests to Koha that include the 'lang' parameter containing time-based SQL injection primitives (SLEEP, pg_sleep, BENCHMARK, WAITFOR), indicative of CVE-2026-72610 exploitation.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-72610
author: Valtersit Threat Intelligence
date: 2026/07/01
logsource:
category: webserver
product: generic
detection:
selection_lang:
http.request.body|contains:
- "lang="
selection_sqli:
http.request.body|contains|all:
- "'"
http.request.body|contains:
- "sleep("
- "pg_sleep("
- "benchmark("
- "waitfor"
- "delay("
condition: selection_lang and selection_sqli
falsepositives:
- Legitimate penetration testing activity
- Web vulnerability scanners (e.g., authenticated scan campaigns)
level: high
tags:
- attack.t1190
- cve.2026.72610
- cwe.89
YARA Rule
rule CVE_2026_72610_Koha_Lang_TimeBased_SQLi
{
meta:
author = "Valtersit Threat Intelligence"
description = "Detects time-based SQL injection payloads stored in Koha patron lang fields (CVE-2026-72610) within logs, database dumps, or web access artifacts"
cve = "CVE-2026-72610"
cwe = "CWE-89"
date = "2026-07-01"
strings:
$lang_param = /lang=[^\s&"']{0,30}/ ascii nocase
$sqli_quote = /lang=[^\s&"']*\x27/ ascii nocase
$sleep_func = "sleep(" ascii nocase
$pg_sleep = "pg_sleep" ascii nocase
$benchmark = "benchmark(" ascii nocase
$waitfor = "waitfor delay" ascii nocase
$comment_style = "--" ascii
$comment_hash = "#" ascii
condition:
any of ($sleep_func, $pg_sleep, $benchmark, $waitfor)
and $lang_param
and (any of ($sqli_quote, $comment_style, $comment_hash))
}
Suricata IDS Rule
alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"ET WEB_SPECIFIC_APPS Koha CVE-2026-72610 Time-Based SQLi in patron lang field"; flow:established,to_server; content:"koha"; http.uri; nocase; content:"lang="; http.request_body; nocase; pcre:"/(?:sleep|pg_sleep|benchmark|waitfor)[[:space:]]*\(/i"; classtype:attempted-dos; sid:2026072610; rev:1; metadata:created_at 2026_07_01, updated_at 2026_07_01, cve CVE-2026-72610;)
Elastic Detection
any where event.category == "web" and
(wildcard(http.request.body, "*lang=*") or wildcard(url.query, "*lang=*")) and
(wildcard(http.request.body, "*sleep(*") or
wildcard(http.request.body, "*pg_sleep*") or
wildcard(http.request.body, "*benchmark(*") or
wildcard(http.request.body, "*waitfor*"))
Supplementary Elastic query (execution phase): monitor database slow-query logs for repeated sleep-type statements during issue-slip printing:
any where event.category == "database" and
wildcard(message, "*sleep*") and
wildcard(message, "*select*")
Splunk SPL Query
For web-access logs (initial injection write):
index=web sourcetype=access_combined ("sleep(" OR "pg_sleep" OR "benchmark(" OR "waitfor")
| regex _raw="(?i)lang="
| eval koha_staff_client=if(match(_raw,"(?i)/cgi-bin/koha/"),"true","false")
| table _time src_ip uri uri_query status http_user_agent koha_staff_client
| sort - _time
For database slow-query logs (stored payload execution):
index=db sourcetype=mysql_slow_query OR sourcetype=mariadb_slow
| regex query="(?i)(sleep\(|pg_sleep|benchmark\()"
| where query_time > 5
| table _time server host user query query_time rows_examined
| stats count by server host user query_time
Wazuh OSSEC Rule
<group name="koha,sql_injection,">
<rule id="100726" level="10" frequency="8" timeframe="120">
<if_sid>31100</if_sid>
<match>sleep\(|pg_sleep|benchmark\(|waitfor</match>
<regex>lang=</regex>
<description>CVE-2026-72610: Possible time-based SQL injection against Koha patron lang field (stored payload or injection attempt).</description>
<group>sql_injection,koha,attack.t1190,</group>
<mitre>
<id>T1190</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 — UNPATCHED. No vendor advisory, code commit, or fixed release has been identified by any tracked source. The affected branches are 24.11.x, 25.05.x, 25.11.x, and 26.05.x (up to and including 24.11.17, 25.05.12, 25.11.06, and 26.05.01).
1) Immediate mitigations:
- Audit all patron records for anomalous
langvalues: sanitize any value that is not a valid locale/language code (i.e., contains quotes,--,#, parentheses, or SQL keywords such assleep,benchmark,waitfor). Clear or reset poisoned fields. - Restrict the
borrowers => edit_borrowerspermission to the minimum set of trusted staff. Review current staff permission assignments and revoke where not strictly required for job duties. - Apply WAF/IDS rules (see Detection Guidance) to flag and optionally block requests carrying time-based SQLi primitives in the
langparameter. - Enable or tune database slow-query logging; alert on recurrent sleep-type statements associated with issue-slip printing.
2) Patch/upgrade steps:
- Monitor the Koha community security announcements and the official Koha download channels for maintenance releases that follow the affected versions (24.11.18+, 25.05.13+, 25.11.07+, 26.05.02+).
- Once a fixed release is published, upgrade promptly through the normal Koha upgrade path spanning the affected maintenance branches. Validate the fix by attempting to store a time-based payload in a test patron's
langfield and confirming it is neutralized or rejected.
3) Long-term hardening:
- Enforce allowlist-based input validation on the
langfield at the application layer (e.g., accept only ISO 639 language codes). - Ensure the
Koha::AdditionalContents->search_for_displayquery pipeline uses parameterized queries/bind variables for all dynamic values rather than raw string concatenation. - Adopt least-privilege role design for the Koha staff client; review permissions periodically and require a second approver for privileged staff-client roles.
- Implement centralized logging and retention for Koha staff-client actions, web access, and database slow-query logs to enable retroactive detection of stored SQLi payloads.
- If the instance is Internet-exposed, place the staff client behind VPN/zero-trust access controls to reduce the reachability of authenticated-only vulnerabilities.
References
- NVD — CVE-2026-72610: https://nvd.nist.gov/vuln/detail/CVE-2026-72610
- MITRE CWE-89 (SQL Injection): https://cwe.mitre.org/data/definitions/89.html
- Koha Community (official project): https://koha-community.org/
- 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-72610 is not listed as of this writing; no vendor-specific advisory or researcher blog has been published for this CVE at the time of this report.
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.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.