{"id":"CVE-2026-57565","kind":"vulnerability","aliases":["CVE-2026-57565"],"related":[],"title":"Readest: authenticated users can overwrite other users' stored ebooks","description":"Readest is a modern, feature-rich ebook reader designed for seamless cross-platform access and an intuitive reading experience. Prior to 0.11.10, the apps/readest-app/src/pages/api/storage/upload.ts route constructed an object key from the authenticated user's identifier and a client-controlled fileName without rejecting path separators or parent-directory traversal. In the R2 backend, apps/readest-app/src/utils/r2.ts placed that key into a new Request URL before signing it, and URL normalization collapsed parent-directory components so the resulting presigned PUT could escape the caller's namespace. An authenticated attacker who knew a target user identifier and book hash could overwrite or poison that user's stored book object and corrupt the associated file_key metadata; the exact cross-tenant escape was verified for the R2 backend. This issue is fixed in version 0.11.10.","summary":"Readest's storage upload route built file keys from a client-supplied file name without blocking path traversal, and the R2 backend normalized those paths. An authenticated attacker can therefore write to another user's stored book object and corrupt its metadata.","severity":"medium","cvss":6.5,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["cloudflare-r2","other","readest","self-hosted"],"not_affected_if":["non-r2-storage","version-0.11.10-or-later"],"how_to_check":"- Check the Readest version in use; affected builds are those before `0.11.10`.\n- If you run Readest with the R2 storage backend, review apps/readest-app/src/pages/api/storage/upload.ts and apps/readest-app/src/utils/r2.ts for the file key construction.","fix":"- Move to Readest `0.11.10` or later.","status":"open","published_at":"2026-11-04T22:18:06+00:00","first_seen_at":"2026-11-04T23:08:49+00:00","triaged_at":"2026-11-04T23:10:05+00:00","updated_at":"2026-11-04T23:10:05+00:00","category":"other","confidence":0.7,"triage":{"at":"2026-11-04T23:10:05Z","model":"claude-haiku-5-5","output":{"fix":"- Move to Readest `0.11.10` or later.","reach":"internet","title":"Readest: authenticated users can overwrite other users' stored ebooks","impact":"medium","summary":"Readest's storage upload route built file keys from a client-supplied file name without blocking path traversal, and the R2 backend normalized those paths. An authenticated attacker can therefore write to another user's stored book object and corrupt its metadata.","audience":"businesses","category":"other","nicknames":[],"who_cares":["readest","self-hosted","cloudflare-r2"],"confidence":0.7,"fix_status":"available","needs_auth":"yes","worst_case":"attacker overwrites another user's stored book and its metadata","analyst_note":"","how_to_check":"- Check the Readest version in use; affected builds are those before `0.11.10`.\n- If you run Readest with the R2 storage backend, review apps/readest-app/src/pages/api/storage/upload.ts and apps/readest-app/src/utils/r2.ts for the file key construction.","plain_action":"","needs_analyst":false,"not_affected_if":["version-0.11.10-or-later","non-r2-storage"],"who_is_affected":"Exposure requires an authenticated account and the R2 storage backend, since the cross-tenant escape was verified there. Operators of Readest instances that use R2 for user book storage are in scope. Instances using other storage backends or running `0.11.10` or later are not affected by this report.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"unknown"},"cost_usd":0.001135,"input_tokens":4460,"output_tokens":1378,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-2026':11A,14A '-57565':12A,15A '0.11.10':90C,201C 'access':82C 'anoth':57B 'apps/readest-app/src/pages/api/storage/upload.ts':92C 'apps/readest-app/src/utils/r2.ts':123C 'associ':179C 'attack':52B,156C 'authent':2A,51B,100C,155C 'backend':46B,122C,194C 'block':40B 'book':61B,164C,174C 'built':29B 'caller':151C 'client':35B,107C 'client-control':106C 'client-suppli':34B 'cloudflar':17B 'cloudflare-r2':16B 'collaps':138C 'compon':142C 'construct':94C 'control':108C 'corrupt':64B,177C 'could':148C,166C 'cross':80C,186C 'cross-platform':79C 'cross-ten':185C 'cve':10A,13A 'design':76C 'directori':117C,141C 'ebook':9A,74C 'escap':149C,188C 'exact':184C 'experi':87C 'featur':72C 'feature-rich':71C 'file':30B,37B,180C 'filenam':109C 'fix':198C 'hash':165C 'host':23B 'identifi':103C,162C 'intuit':85C 'issu':196C 'key':31B,97C,126C,181C 'knew':158C 'metadata':66B,182C 'modern':70C 'name':38B 'namespac':153C 'new':129C 'normal':47B,137C 'object':62B,96C,175C 'overwrit':5A,167C 'parent':116C,140C 'parent-directori':115C,139C 'path':41B,49B,112C 'place':124C 'platform':81C 'poison':169C 'presign':146C 'prior':88C 'put':147C 'r2':18B,45B,121C,193C 'read':86C 'reader':75C 'readest':1A,20B,24B,67C 'reject':111C 'request':130C 'result':145C 'rich':73C 'rout':28B,93C 'seamless':78C 'self':22B 'self-host':21B 'separ':113C 'sign':133C 'storag':26B 'store':8A,60B,173C 'suppli':36B 'target':160C 'tenant':187C 'therefor':54B 'travers':42B,118C 'upload':27B 'url':131C,136C 'user':3A,7A,58B,101C,161C,171C 'verifi':190C 'version':200C 'without':39B,110C 'write':55B","nicknames":[],"mitigations":[],"who_affected":"Exposure requires an authenticated account and the R2 storage backend, since the cross-tenant escape was verified there. Operators of Readest instances that use R2 for user book storage are in scope. Instances using other storage backends or running `0.11.10` or later are not affected by this report.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":[],"ptokens":[],"labels":["cloudflarer2","medium","other","readest","selfhosted"],"campaign_type":null,"first_public_at":"2026-10-15T04:56:37+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N","cvss_by":"security-advisories@github.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-57565","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-57565","severity":null,"published_at":"2026-11-04T22:18:06+00:00","modified_at":"2026-11-04T22:18:06+00:00","first_seen_at":"2026-11-04T23:08:49+00:00","fetched_at":"2026-11-04T23:08:49+00:00","note":null}],"documents":[{"id":71165,"url":"https://github.com/readest/readest/commit/495783d04516d05b2eb10f8f8bad297d436b36de","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":71166,"url":"https://github.com/readest/readest/releases/tag/v0.11.10","title":"Release notes: github.com","kind":"release","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release notes: github.com"},{"id":71171,"url":"https://github.com/readest/readest/security/advisories/GHSA-mfmj-2frf-vhgw","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-10-15T04:56:37+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"exploit_sources":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}