VYPR
Moderate severityNVD Advisory· Published Nov 15, 2024· Updated Nov 15, 2024

Information Disclosure in janeczku/calibre-web

CVE-2021-3986

Description

A vulnerability in janeczku/calibre-web allows unauthorized users to view the names of private shelves belonging to other users. This issue occurs in the file shelf.py at line 221, where the name of the shelf is exposed in an error message when a user attempts to remove a book from a shelf they do not own. This vulnerability discloses private information and affects all versions prior to the fix.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Calibre-Web exposes private shelf names to unauthorized users via error messages when attempting to remove a book from a shelf they don't own.

Vulnerability

Description

Calibre-Web, a web application for browsing and managing Calibre ebook libraries, contains an information disclosure vulnerability in its shelf management functionality. The bug resides in the file shelf.py at line 221, where an error message returned when a user attempts to remove a book from a shelf they are not authorized to modify includes the name of the shelf [1]. This occurs in the remove_from_shelf function, which constructs a response string containing shelf.name even for unauthorized requests.

Exploitation

An attacker with a valid user account on the Calibre-Web instance can exploit this vulnerability by sending a request to remove a book from any shelf, including private shelves belonging to other users. Since the error message is emitted before permission checks are completed, the shelf's name is disclosed regardless of the attacker's authorization level [3]. No special privileges are required beyond being logged in.

Impact

Successful exploitation allows an authenticated attacker to enumerate the names of private shelves created by other users. This disclosure violates user privacy expectations and could reveal sensitive information if users name shelves with descriptive or confidential titles (e.g., project names or personal categories).

Mitigation

The issue has been patched in commit 6f5390ead5df9779ac81fadefffb476e03f93548 [3], which modifies the error messages in shelf.py to omit the shelf's name. Users should upgrade to a patched version of Calibre-Web to remediate this vulnerability. No known public exploit code exists, but the attack vector is trivial to execute.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
calibrewebPyPI
< 0.6.150.6.15

Affected products

2

Patches

1
6f5390ead5df

Changed error message in case of trying to delete a shelf unauthorized

https://github.com/janeczku/calibre-webOzzie IsaacsNov 20, 2021via ghsa
2 files changed · +4 13
  • cps/db.py+0 9 modified
    @@ -807,15 +807,6 @@ def speaking_language(self, languages=None):
                     .group_by(text('books_languages_link.lang_code')).all()
             for lang in languages:
                 lang.name = isoLanguages.get_language_name(get_locale(), lang.lang_code)
    -            #try:
    -            #    if lang.lang_code.lower() == "und":
    -            #        lang.name = isoLanguages.get_language_name(get_locale(), lang.lang_code)
    -            #        # lang.name = _("Undetermined")
    -            #    else:
    -            #        cur_l = LC.parse(lang.lang_code)
    -            #        lang.name = cur_l.get_language_name(get_locale())
    -            #except UnknownLocaleError:
    -            #    lang.name = _(isoLanguages.get(part3=lang.lang_code).name)
             return languages
     
         def update_title_sort(self, config, conn=None):
    
  • cps/shelf.py+4 4 modified
    @@ -122,8 +122,8 @@ def search_to_shelf(shelf_id):
             return redirect(url_for('web.index'))
     
         if not check_shelf_edit_permissions(shelf):
    -        log.warning("You are not allowed to add a book to the the shelf: {}".format(shelf.name))
    -        flash(_(u"You are not allowed to add a book to the the shelf: %(name)s", name=shelf.name), category="error")
    +        log.warning("You are not allowed to add a book to the shelf".format(shelf.name))
    +        flash(_(u"You are not allowed to add a book to the shelf"), category="error")
             return redirect(url_for('web.index'))
     
         if current_user.id in ub.searched_ids and ub.searched_ids[current_user.id]:
    @@ -215,10 +215,10 @@ def remove_from_shelf(shelf_id, book_id):
         else:
             if not xhr:
                 log.warning("You are not allowed to remove a book from shelf: {}".format(shelf.name))
    -            flash(_(u"Sorry you are not allowed to remove a book from this shelf: %(sname)s", sname=shelf.name),
    +            flash(_(u"Sorry you are not allowed to remove a book from this shelf"),
                       category="error")
                 return redirect(url_for('web.index'))
    -        return "Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name, 403
    +        return "Sorry you are not allowed to remove a book from this shelf", 403
     
     
     @shelf.route("/shelf/create", methods=["GET", "POST"])
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.