Kolibri has Unauthenticated Server-Side Request Forgery (SSRF) in RemoteFacilityUserViewset
Several Kolibri API endpoints accept an unvalidated baseurl parameter and fetch attacker-controlled URLs from the Kolibri server, reflecting the response body back to the caller. The original report identified two endpoints on the RemoteFacilityUser* viewsets; remediation review found two further reflection points on the same pattern. The GET endpoint was unauthenticated.
Reported:
GET /api/auth/remotefacilityuser → RemoteFacilityUserViewset (kolibri/core/auth/api.py:1570). No authentication required.POST /api/auth/remotefacilityauthenticateduserinfo → RemoteFacilityUserAuthenticatedViewset (kolibri/core/auth/api.py:1594). Authentication is checked against the *remote* server rather than the local Kolibri.Found during remediation:
POST /api/public/setupwizard/loddata → setup wizard's remote-signup proxy (kolibri/plugins/setup_wizard/api.py). Reachable on unprovisioned devices.GET /api/public/networklocation/<id>/facilities/ → NetworkLocationFacilitiesView (kolibri/core/discovery/api.py). Authenticated but with the same Response(remote_payload) pattern.Two compounding issues:
1. Response reflection — these endpoints returned the remote server's JSON body more or less verbatim to the caller (Response(response.json()), Response(facility_info["users"]), etc.).
2. No restriction on the remote target — baseurl was validated only by URLValidator(schemes=["http", "https"]). NetworkClient.build_for_address() would connect to any host with a valid Kolibri-shaped /api/public/info/ response, and requests followed 30x redirects by default, so a hostile peer could pivot the fetch to an arbitrary host (cloud metadata, internal services) before reflection.
GET vector (RemoteFacilityUserViewset):
The viewset fetched <baseurl>/api/public/facilitysearchuser/ and returned Response(response.json()). An attacker-controlled baseurl returned a 302 to an arbitrary internal URL; requests followed the redirect, and the redirected response body was returned to the attacker.
POST vector (RemoteFacilityUserAuthenticatedViewset):
get_remote_users_info() fetched <baseurl>/api/public/facilityuser/ with Basic Auth and the viewset returned Response(facility_info["users"]). A malicious baseurl returned crafted user-shaped JSON; arbitrary smuggled fields were reflected back to the caller. The setup wizard and NetworkLocationFacilitiesView endpoints had the same shape on different remote URLs.
The vulnerability can be reproduced by pointing baseurl at an attacker-controlled HTTP server that:
1. Responds to GET /api/public/info/ with a valid Kolibri info payload (so NetworkClient.build_for_address() succeeds).
2. GET vector: responds to GET /api/public/facilitysearchuser/ with a 302 redirect to the target URL. The redirected response body is reflected via Response(response.json()).
3. POST vector: responds to the relevant remote URL with crafted JSON containing additional fields. The full JSON is reflected.
A working PoC has been retained internally and is not published with this advisory.
GET with JSON and no special request headers./metadata/v1.json) — reachableMetadata-Flavor / Metadata / token headers that the attacker could not inject)The earlier draft asserted port scanning via a timing oracle and generic "internal network mapping." The reflection vector reads response bodies directly when the target speaks JSON; timing-based scanning of arbitrary TCP services was not demonstrated and is not the headline risk.
Four layers of defence:
1. Response sanitisation. Each affected endpoint now coerces the remote response to a documented shape before returning it. Smuggled fields are dropped.
2. Authentication. The previously-open RemoteFacilityUser* endpoints now require an authenticated caller (or an unprovisioned device, for setup-wizard flows).
3. Cross-host redirect blocking. Remote-fetch HTTP sessions refuse 30x responses that point to a different hostname. Same-host redirects still work.
4. Peer allowlist. Endpoints that accept a caller-supplied baseurl resolve it
This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality low, integrity none, availability none.
The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N
CVE-2026-48053 is classified as CWE-918: Server-Side Request Forgery (SSRF). The server fetches a URL supplied by the caller, which can be pointed at internal systems it alone can reach.
CVE-2026-48053 is recorded against 2 packages.
Published on 13 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.
github.com (Web)
github.com (Package)
github.com (Web)
pypi.org (Package)
github.com (Advisory)
nvd.nist.gov (Advisory)
These advisories are the same class of weakness (CWE-918: Server-Side Request Forgery (SSRF)) in other software:
Details
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| kolibri | — | 0.19.4 |
| unknown | — | — |
References
Vulnerability Monitoring
CVE-2026-48053 is rated CVSS 5.8 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.
Set Up Free Alerts →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.
Stay up to date with the latest from Boteraser.
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Manage your cookie preferences below:
Essential cookies enable basic functions and are necessary for the proper function of the website.
CloudFlare provides web performance and security solutions, enhancing site speed and protecting against threats.
Service URL: developers.cloudflare.com (opens in a new window)
These cookies are needed for adding comments on this website.
These cookies are used for managing login functionality on this website.
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Service URL: policies.google.com (opens in a new window)
You can find more information in our Cookie Policy and Privacy Policy.