https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43284 Bug ID: 43284 Summary: ILS-DI: patron data/circulation services lack authentication Initiative type: --- Sponsorship --- status: Product: Koha Version: 26.05 Hardware: All OS: All Status: NEW Severity: major Priority: P5 - low Component: Web services Assignee: koha-bugs@lists.koha-community.org Reporter: akhdanarif456@gmail.com QA Contact: testopia@bugs.koha-community.org Target Milestone: --- Created attachment 203573 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=203573&action=edit Proof of concept in local deployment of 26.05.02 with ILS-DI enabled and allowlist ip in ILS-DI:AuthorizedIPs The ILS-DI services (opac/ilsdi.pl) expose patron data and circulation operations (renew loan, place hold) with no authentication and no per-user authorization. The only access control is the ILS-DI:AuthorizedIPs IP allowlist. Once a request passes that IP check, anyone can read any patron's personal data and perform actions on behalf of any patron, using only predictable numeric IDs. Exploitable when: ILS-DI is enabled and the client IP is in ILS-DI:AuthorizedIPs . Where those hold, authentication is entirely absent. Reproduce: 1. Setup: enable ILS-DI = 1, add attacker IP to ILS-DI:AuthorizedIPs. 2. Read + enumerate patron data (no auth): GET /cgi-bin/koha/ilsdi.pl?service=GetPatronInfo&patron_id=2&show_contact=1 3. State-changing (no auth): GET /cgi-bin/koha/ilsdi.pl?service=RenewLoan&patron_id=2&item_id=1 & GET /cgi-bin/koha/ilsdi.pl?service=HoldTitle&patron_id=2&bib_id=1&request_location=127.0.0.1 Actual Results: 1. GetPatronInfo returns full PII (address, phone, cardnumber, city) for any patron; enumeration dumps the whole patron database. 2. RenewLoan extends the loan: date_due changed 2026-08-26 → 2026-08-31 ( <success>1</success>). 3. HoldTitle creates a hold on behalf of the victim: reserves count 0 → 1. All verified on a live local deployment of 26.05.02. Expected Results: Patron-facing services should require the caller to authenticate as that patron (via AuthenticatePatron, which already exists) or as staff with permission. the IP allowlist should not be the only control. Security Hardening Gap: 1. IP allowlist is single-factor, and IPs can be spoofed/shared (VPN, NAT, shared server). If a discovery layer is used by many people or its IP is shareable, anyone on that IP can access all patron data. 2. No per-user audit trail. All requests are anonymous, hard to forensically trace. 3. CSRF exemption for /ilsdi.pl remains a problem for state-changing services if the IP gate is bypassed. Root cause: opac/ilsdi.pl never calls checkauth(); it sets an anonymous userenv and relies solely on the IP allowlist. C4/ILSDI/Services.pm looks up objects purely by numeric ID with no ownership check (GetPatronInfo, RenewLoan, HoldTitle, HoldItem, GetPatronStatus, GetServices, LookupPatron). Contrast: CancelHold does contain an ownership check — so the missing checks elsewhere are an inconsistency/oversight, not uniform design. -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.