Conversation
Authenticated users shouldn't be able to generate/delete kobo auth tokens for other users if they're not admin.
The lxml.etree.fromstring() function use the default XML parser, which resolves external entities because XML handling defaults in Python sucks. There is no need for such dangerous misfeatures in calibre-web, so let's disable it. A user able to upload epub/fb2 could add something like this to the file: ```xml <?xml version="1.0"?> <!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> <container><rootfiles><rootfile full-path="&xxe;"/></rootfiles></container> ``` and obtain the content of the `/etc/passwd` file, which is bad™.
When an OAuth provider_user_id is already linked to User A, and User B authenticates with the same OAuth identity, User B is silently logged in as User A. This is by design for single-user OAuth, but in a multi-user environment it means: if an attacker gains access to the same OAuth provider account (e.g., a shared GitHub org account, or by compromising the OAuth provider), they can log in as the linked Calibre-Web user with no password needed.
hashlib.md5(dbpath) returns a hash object, not a hex string. Comparing a string (md5Checksum) to a hash object with != always returns True. This means the DB-replacement code path is always entered, allowing an attacker who sends a forged notification (with the known static token) to trigger an arbitrary metadata.db download from GDrive, replacing the live database.
No need to dump Gmail OAuth client_secret, refresh_token, and access_token in the debug ZIP in plaintext.
The `serve_book` function uses `get_book()` which performs no access filtering: it simply fetches by ID. Compare with `read_book` at web.py:1562 which correctly uses `get_filtered_book()`. The `common_filters()` function enforces per-user tag restrictions, language restrictions, and hidden-book rules.
The typical Linux umask of 0022, meaning the encrypted file is world-readable (-rw-r--r--). Any OS-level user on the same system can read the key and decrypt the encrypted credentials from app.db.
This is reachable only by the admin users, but is still a straightforward RCE vector, if only via SQLite's `ATTACH DATABASE` trick
Books.atom_timestamp returned Books.timestamp (date added), which is set at import and never changes. OPDS clients use atom:updated to decide whether a book has changed on the server, so cover swaps, metadata edits, and any other post-import change were invisible to sync clients; they would keep serving the stale cover and title until a manual refresh. Atom RFC 4287 defines updated as "the most recent instant in time when an entry or feed was modified", and Calibre already tracks that field as last_modified, bumping it on every metadata and cover edit. Switching the property to return last_modified (with a fallback to timestamp when last_modified is NULL) aligns Calibre-Web's behaviour with the Atom contract. This change only affects the OPDS feed's atom:updated element. Kobo sync uses its own last_modified comparison path, so it is unaffected.
Both comicvine.py and douban.py return None instead of [] when an HTTP error occurs during a metadata search. The consumer in search_metadata.py iterates the result directly, which raises TypeError: 'NoneType' object is not iterable and crashes the server on single-threaded deployments. Fixes #3606
…ta-provider-none-crash'
…reflects-modifications'
|
Interesting: File/line(s): cps/gdrive.py:141-143 |
|
CI workflow https://github.com/iiab/calibre-web/actions/runs/24815679973/job/72631069725?pr=370 failed as follows: (@Akatama does this look familiar?!) |
|
@holta Yes. Upstream does not have integration-tests-requirements.txt. So that step will fail. |
|
Thanks @deldesir. Thanks @chapmanjacobd for reviewing. And thanks @Akatama for the reminder — confirmed after merge: "Calibre-Web Smoke test with IIAB install / test-install" (8 min) https://github.com/iiab/calibre-web/actions/runs/24831221738/job/72679947319 |
This PR includes several critical security enhancements, bug fixes, and general stability improvements.
Security Fixes:
Bug Fixes & Stability: