Skip to content

CVE-2026-58466: Verified Repro With Script Download

CVE-2026-58466: AutoBangumi before 3.2.8 seeds a default admin account on empty databases, allowing unauthenticated users to log in with publicly known default credentials and gain full control.

CVE-2026-58466 is verified against EstrellaXD/Auto_Bangumi · standalone application (Python/FastAPI). Affected versions: < 3.2.8. Fixed in 3.2.8. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00219.

REPRO-2026-00219 EstrellaXD/Auto_Bangumi · standalone application (Python/FastAPI) Variant found Jul 3, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.3
Confidence
HIGH
Reproduced in
14m 56s
Tool calls
128
Spend
$2.02
01 · Overview

What Is CVE-2026-58466?

CVE-2026-58466 is a critical (CVSS 9.3) use-of-default-credentials vulnerability (CWE-1392) in AutoBangumi that seeds a default administrator account on empty databases, letting unauthenticated attackers log in and gain full control. Pruva reproduced it (reproduction REPRO-2026-00219).

02 · Severity & CVSS

CVE-2026-58466 Severity & CVSS Score

CVE-2026-58466 is rated critical severity, with a CVSS base score of 9.3 out of 10.

CRITICAL threat level
9.3 / 10 CVSS base
Weakness CWE-1392 Use of Default Credentials

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected EstrellaXD/Auto_Bangumi Versions

EstrellaXD/Auto_Bangumi · standalone application (Python/FastAPI) versions < 3.2.8 are affected.

How to Reproduce CVE-2026-58466

$ pruva-verify REPRO-2026-00219
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00219/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-58466

Authorization bypass — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

default credentials admin/adminadmin submitted as OAuth2 form to POST /api/v1/auth/login

Attack chain
  1. fresh empty DB
  2. startup add_default_user() seeds admin/adminadmin
  3. POST /api/v1/auth/login
  4. UserDatabase.auth_user
  5. verify_password(adminadmin) succeeds
  6. admin JWT (sub=admin) issued
  7. token cookie grants admin API access (/api/v1/rss, /api/v1/log)
Variants tested

Two bypasses of CVE-2026-58466 reproduced on the FIXED/LATEST AutoBangumi official Docker images. Variant 1 (bypass): the hard-coded default credentials admin/adminadmin still authenticate via POST /api/v1/auth/login on the patched :latest (=3.2.8 build) and on :3.3.0-beta.2, granting an admin JWT and full admin API a…

How the agent worked 334 events · 128 tool calls · 15 min
15 minDuration
128Tool calls
106Reasoning steps
334Events
Agent activity over 15 min
Support
13
Hypothesis
2
Repro
179
Judge
37
Variant
99
0:0014:56

Root Cause and Exploit Chain for CVE-2026-58466

Versions: AutoBangumi < 3.2.8 (reproduced on the official

AutoBangumi (a FastAPI-based bangumi/auto-download manager) seeds a hard-coded default administrator account — admin / adminadmin — whenever its users database table is empty. The seeding happens unconditionally on startup via add_default_user() in backend/src/module/database/user.py. Because the credentials are hard-coded and publicly visible in the source, an unauthenticated remote attacker can submit them to the real authentication endpoint (POST /api/v1/auth/login) on a freshly deployed instance and receive a valid administrator JWT, gaining full administrative control of the application (RSS feed configuration, downloader configuration, server logs, and every authenticated API endpoint).

  • Package/component affected: AutoBangumi backend — module/database/user.py (UserDatabase.add_default_user), invoked from module/update/startup.py (first_run/start_up) during module/core/program.py startup.
  • Affected versions: AutoBangumi < 3.2.8 (reproduced on the official Docker image ghcr.io/estrellaxd/auto_bangumi:3.2.6).
  • Risk level: Critical (CVSS v3 max 9.8 / v4 9.3). CWE-1392 Use of Default Credentials. Remote, unauthenticated, low complexity, full confidentiality/integrity/availability impact on the application.
  • Consequences: Complete administrative takeover of a fresh AutoBangumi instance — an attacker can read/change RSS feeds, reconfigure the downloader (including credentials), read server logs, and exercise all authenticated API endpoints.

Impact Parity

  • Disclosed/claimed maximum impact: Unauthenticated attacker authenticates as administrator using publicly known default credentials and gains full administrative access (authz bypass / default credentials).
  • Reproduced impact from this run: Full parity. Against the real AutoBangumi 3.2.6 product (official Docker image, fresh empty database) the default credentials admin/adminadmin were submitted to POST /api/v1/auth/login and returned HTTP 200 + an admin JWT (sub: admin). That JWT, sent as the token session cookie, granted access to admin-only endpoints (/api/v1/rss returned the RSS config list, /api/v1/log returned the server log stream) — proving full administrative access via the remote API.
  • Parity: full
  • Not demonstrated: N/A — the claimed impact (default-credential authentication bypass → admin access) was reproduced end-to-end through the real remote API surface.

Root Cause

UserDatabase.add_default_user() queries the users table; if it is empty it inserts a single user with hard-coded credentials:

# backend/src/module/database/user.py
def add_default_user(self):
    statement = select(User)
    ...
    if len(users) != 0:
        return
    user = User(username="admin", password=get_password_hash("adminadmin"))
    self.session.add(user)
    self.session.commit()
    logger.info("[Database] Created default admin user")

This method is called on every startup from module/update/startup.py (start_up and first_run), which are invoked by module/core/program.py during the FastAPI lifespan startup. On a fresh deployment (no persisted database) the table is empty, so the default admin/adminadmin account is created. The login endpoint (module/api/auth.py, POST /api/v1/auth/login) validates the submitted credentials against the database via UserDatabase.auth_user, which uses verify_password. Because the seeded password hash matches adminadmin, the default credentials authenticate successfully and a JWT (sub: admin) is issued. The session is registered in the in-memory active_user map, and the get_current_user dependency accepts the token cookie for all protected endpoints.

There is no forced password change, no setup-completion gate on the login endpoint, and no randomization of the default password, so the publicly known credentials remain valid until an administrator manually changes them through the (unauthenticated-only-before-setup) setup wizard.

Fix commit referenced by the advisory: 487bdfec545e805ae416e6ddf28651bd274d6a73 ("fix(api): harden pre-auth setup endpoints (#1041, #1044)"). Note: inspection of that commit shows it hardens the SSRF behavior of the pre-auth /setup/test-* endpoints and qBittorrent 5.2 login compatibility — it does not remove or randomize the default admin/adminadmin account. Correspondingly, the negative control below shows the default credentials remain exploitable in 3.2.8.

Reproduction Steps

  1. The self-contained script is bundle/repro/reproduction_steps.sh.
  2. What it does:
    • Pulls the official AutoBangumi Docker images ghcr.io/estrellaxd/auto_bangumi:3.2.6 (vulnerable) and :3.2.8 (claimed patch).
    • For the vulnerable version, starts two clean instances each with a fresh empty Docker volume (so the users table is empty and add_default_user() triggers), waits for Application startup complete, and captures the startup log (which records [Database] Created default admin user).
    • Drives the real remote API from inside each container (the Docker bridge is not routable from the sandbox host, so HTTP probes are executed via docker exec against 127.0.0.1:7892): POST /api/v1/auth/login with form username=admin&password=adminadmin.
    • On a 200 + JWT, reuses the token session cookie to call the admin-only endpoints GET /api/v1/rss and GET /api/v1/log.
    • Runs the same flow against :3.2.8 as a negative control (two attempts).
    • Writes all HTTP request/response artifacts to bundle/artifacts/http/, startup logs to bundle/logs/, and the runtime manifest to bundle/repro/runtime_manifest.json.
  3. Expected evidence of reproduction:
    • Startup log line [Database] Created default admin user.
    • Login response HTTP 200 with access_token JWT and set-cookie: token=<JWT>; HttpOnly.
    • JWT payload decodes to {"sub":"admin", ...}.
    • GET /api/v1/rss200 [] (authenticated RSS config).
    • GET /api/v1/log200 server log text (authenticated).

Evidence

  • Run log: bundle/logs/run.log (full execution transcript, both runs).
  • Startup logs: bundle/logs/vuln-1-startup.log, bundle/logs/vuln-2-startup.log, bundle/logs/fixed-1-startup.log, bundle/logs/fixed-2-startup.log.
  • HTTP artifacts: bundle/artifacts/http/vuln-{1,2}-login.json, vuln-{1,2}-rss.json, vuln-{1,2}-log.json, fixed-{1,2}-login.json.
  • Runtime manifest: bundle/repro/runtime_manifest.json.

Key excerpts (vulnerable 3.2.6, attempt 1):

Startup seeding:

[Database] Schema version is now 9.
[Database] Created default admin user
[Core] No db file exists, create database file.
Application startup complete.
Uvicorn running on http://0.0.0.0:7892

Login with default credentials (bundle/artifacts/http/vuln-1-login.json):

{
  "method": "POST",
  "path": "/api/v1/auth/login",
  "status": 200,
  "set_cookie": "token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6...}; HttpOnly; Max-Age=86400; Path=/; SameSite=lax",
  "body": "{\"access_token\":\"eyJ...sub\":\"admin\"...\",\"token_type\":\"bearer\"}"
}

The JWT payload decodes to {"sub":"admin","exp":...} — authenticated as the administrator.

Admin-only endpoint access with the session cookie (bundle/artifacts/http/vuln-1-rss.json, vuln-1-log.json):

{ "method": "GET", "path": "/api/v1/rss", "status": 200, "body": "[]" }
{ "method": "GET", "path": "/api/v1/log", "status": 200, "body": "[2026-07-03 ...] INFO ... Version 3.2.6 ..." }

Environment: Official Docker images on the host Docker daemon (client 29.1.3); AutoBangumi 3.2.6 backend (Python 3.13, uvicorn/FastAPI, SQLite) inside Alpine containers; webui port 7892; HTTP probes executed in-container via docker exec python3.

Negative control (3.2.8): The 3.2.8 image also logs [Database] Created default admin user on a fresh database and accepts the admin/adminadmin login with HTTP 200 + an admin JWT in both attempts (bundle/artifacts/http/fixed-{1,2}-login.json). This indicates the advisory-referenced fix commit (487bdfec) addresses the related SSRF issue (#1041) and does not remediate the hard-coded default-credentials seeding; the add_default_user() source is byte-identical from 3.2.6 through HEAD.

Recommendations / Next Steps

  • Primary fix: Do not seed a hard-coded default administrator. Either (a) require the initial setup wizard to create the first admin account with a user-chosen password before any login is possible, or (b) generate a random one-time bootstrap password and display it once in the startup log / a bootstrap file, never reusing a public constant.
  • Defense in depth: Gate POST /api/v1/auth/login behind setup completion (the existing .setup_complete sentinel) so login is rejected until the operator has finished initial configuration.
  • Upgrade guidance: Operators should immediately change the admin password on any deployed instance and avoid exposing port 7892 to untrusted networks. Treat 3.2.8 as still affected for this specific CVE until a corrected fix that removes the default seeding is released.
  • Testing: Add a regression test asserting that a fresh empty database never contains a login-capable account with a known password, and that POST /api/v1/auth/login fails before setup completion.

Additional Notes

  • Idempotency: The script removes its containers/volumes on entry and exit (trap cleanup EXIT) and was executed twice consecutively; both runs exited 0 with identical positive evidence (VULN_LOGIN_OK=1, VULN_ADMIN_ACCESS_OK=1).
  • Networking note: In this sandbox the Docker bridge network is not routable from the host, so port-mapped requests from the host fail with "connection refused". The script therefore performs all HTTP probes from inside the container via docker exec, exercising the same real 127.0.0.1:7892 listener that uvicorn serves — this is the genuine application HTTP surface, not a mock.
  • Scope note: The claim surface (api_remote) was satisfied through the real authentication endpoint and real admin API endpoints of the running product; no sanitizers were used (sanitizer_used=false); the JWT is a real HS256 token signed by the running application.
  • Limitation: The default credentials were located in the source (admin/adminadmin) rather than supplied by the NVD entry, as the ticket noted the NVD entry omits them; they are confirmed correct by the runtime login success.

Variant Analysis & Alternative Triggers for CVE-2026-58466

Versions: versions (as tested):

The parent RCA reproduced the hard-coded default-credential takeover (admin/adminadmin) on AutoBangumi 3.2.6 via POST /api/v1/auth/login and noted that the advisory-referenced "fix" (commit 487bdfec, version 3.2.8) is SSRF hardening of the pre-auth /setup/test-* endpoints — it does not touch add_default_user() or the login endpoint, and the 3.2.8 negative control still accepted the default credentials.

This variant stage confirms two materially distinct bypasses/variants on the FIXED and LATEST official Docker images (ghcr.io/estrellaxd/auto_bangumi:latest = the 3.2.8 build, and :3.3.0-beta.2):

  • Variant 1 — BYPASS (same root cause, fixed version): The default credentials admin/adminadmin still authenticate via POST /api/v1/auth/login on the patched :latest (=3.2.8) and on :3.3.0-beta.2, granting a real admin JWT and full admin API access (/api/v1/rss → 200). The seeding code and login handler are byte-identical (modulo an async DB refactor) from 3.2.6 through HEAD, so the referenced patch is ineffective for this CVE — the original exploit is itself a bypass.
  • Variant 2 — ALTERNATE TRIGGER (different entry point, fixed version): The pre-auth POST /api/v1/setup/complete endpoint, reachable on any fresh instance (GET /api/v1/setup/status{"need_setup":true}), calls db.user.update_user("admin", UserUpdate(username=…, password=…)) and resets the auto-seeded admin account's username/password to attacker-chosen values without ever needing the default credentials. The attacker then logs in with their own credentials and obtains full admin API access. This is a different entry point (/api/v1/setup/complete vs /api/v1/auth/login), the same fresh-instance admin-takeover impact, and it also reproduces on the fixed/latest version — meaning a fix that only gates /auth/login would not stop it.

A third candidate, the DEV_AUTH_BYPASS path (get_current_user returns "dev_user" when module.__version__ is unimportable → VERSION == "DEV_VERSION"), was explicitly ruled out for the official images: they ship a real VERSION (3.2.8 / 3.3.0-beta.2), and a no-auth GET /api/v1/rss returns 401. It is documented as a latent source-install concern, not claimed as a production variant.

Fix Coverage / Assumptions

  • Invariant the original fix relies on: that the only pre-auth security-relevant surface in 3.2.8 is the SSRF reach of /setup/test-downloader / /setup/test-rss and the raw-error echo from those probes.
  • Code paths it explicitly covers: backend/src/module/api/setup.py (_validate_scheme, _validate_url, server-side-only error logging) and the qBittorrent client login/leak fixes. See patch_analysis.md.
  • What the fix does NOT cover: add_default_user() seeding, the /api/v1/auth/login endpoint, the /api/v1/setup/complete admin-account reset, and get_current_user/check_login_ip. git diff 3.2.6..HEAD shows no change to user.py/auth.py/security/api.py root-cause logic; the 3.3.0-beta.2 changes are an async-DB refactor + cookie samesite="strict" + logout GET→POST, none of which add a setup gate or remove the default credentials.

Variant / Alternate Trigger

Variant 1 — default-credential login bypass (same root cause)
  • Entry point: POST /api/v1/auth/login (FastAPI OAuth2 password form, port 7892). Dependency: Depends(check_login_ip) only — login_whitelist defaults to [] (allow all). No setup-completion gate.
  • Code path: startup start_up()/first_run() (module/update/startup.py) → UserDatabase.add_default_user() (module/database/user.py) seeds User(username="admin", password=get_password_hash("adminadmin")) on an empty users table → attacker POSTs username=admin&password=adminadminauth_user()verify_password(adminadmin) succeeds → _issue_token sets token cookie + returns access_token (JWT sub=admin) → cookie grants admin API access.
  • Result on fixed/latest: :latest (3.2.8) and :3.3.0-beta.2 both return HTTP 200 + admin JWT; /api/v1/rss200 [].
Variant 2 — /api/v1/setup/complete pre-auth takeover (alternate trigger)
  • Entry point: POST /api/v1/setup/complete (JSON body, no auth dependency). Guard is only _require_setup_needed(), which passes on a fresh instance because config/.setup_complete does not exist and settings.dict() == Config().dict() (fresh defaults).
  • Code path: _require_setup_needed() passes → handler step 1 calls db.user.update_user("admin", UserUpdate(username=req.username, password=req.password)) (module/api/setup.py:302) which commits the rename + new password for the auto-seeded admin account before any config save → step 4 creates the .setup_complete sentinel. The attacker then calls POST /api/v1/auth/login with their chosen creds → admin JWT (sub=pwned) → GET /api/v1/rss200.
  • Notable: the user-account reset commits in step 1 before the config save in step 2, so even a "failed" /setup/complete (e.g. invalid downloader) would still have changed the admin credentials; and because /auth/login has no setup gate, the new creds are immediately usable.
  • Result on fixed/latest: on :latest (3.2.8), GET /api/v1/setup/status{"need_setup":true,"version":"3.2.8"}; POST /api/v1/setup/complete200 "Setup completed successfully."; login pwned/pwnedpw1200 + JWT sub=pwned; /api/v1/rss200; afterwards admin/adminadmin401 "User not found" (account taken over).
Ruled-out candidate — DEV_AUTH_BYPASS
  • module/security/api.py: DEV_AUTH_BYPASS = VERSION == "DEV_VERSION"; if active, get_current_user returns "dev_user" for all protected endpoints with zero credentials (a distinct no-creds auth bypass).

  • Ruled out for official images: module.__version__.VERSION resolves to 3.2.8 / 3.3.0-beta.2 (real version shipped); no-auth GET /api/v1/rss401 Unauthorized on every tested image. Latent only for source installs missing module/__version__; not claimed as a production variant.

  • Package/component affected: AutoBangumi backend — module/database/user.py (add_default_user), module/api/auth.py (login), module/api/setup.py (complete_setup), invoked from module/update/startup.py.

  • Affected versions (as tested):

    • ghcr.io/estrellaxd/auto_bangumi:3.2.6 (reported VERSION 3.2.6) — vulnerable baseline.
    • ghcr.io/estrellaxd/auto_bangumi:latest (reported VERSION 3.2.8, the claimed patch) — both variants reproduce.
    • ghcr.io/estrellaxd/auto_bangumi:3.3.0-beta.2 (reported VERSION 3.3.0-beta.2, latest beta) — Variant 1 reproduces.
  • Risk level: Critical. CWE-1392 (Use of Default Credentials) for Variant 1; CWE-306 (Missing Authentication for Critical Function / first-run takeover) for Variant 2. Remote, unauthenticated, low complexity, full admin takeover.

  • Consequences: Complete administrative takeover of a fresh AutoBangumi instance — RSS feed config, downloader config (incl. credentials), server logs, and all authenticated API endpoints.

Impact Parity

  • Disclosed/claimed maximum impact (parent CVE): unauthenticated attacker authenticates as administrator using publicly known default credentials and gains full administrative access.
  • Reproduced impact from this variant run: full parity.
    • Variant 1: default admin/adminadmin200 + admin JWT (sub=admin) → /api/v1/rss 200 [] on the patched :latest and :3.3.0-beta.2.
    • Variant 2: pre-auth /setup/complete → attacker creds pwned/pwnedpw1200 + admin JWT (sub=pwned) → /api/v1/rss 200 [] on :latest.
  • Parity: full.
  • Not demonstrated: N/A — the claimed admin-takeover impact was reproduced end-to-end through the real remote API on the fixed/latest product. No memory-corruption / RCE primitive is in scope for this CVE.

Root Cause

The same underlying bug — a fresh AutoBangumi instance auto-seeds a known admin account and exposes unauthenticated paths to authenticate as / reset that account before any operator configuration — is still reachable because the referenced fix (487bdfec / 3.2.8) is SSRF hardening of /setup/test-* and does not modify the seeding, the login endpoint, or the setup-complete handler. add_default_user() is byte-identical (modulo async refactor) from 3.2.6 through 3.3.0-beta.2 (c8f402fd) and main HEAD (b090ec7b); the login handler gained no setup gate. Variant 2 additionally exploits that /api/v1/setup/complete is pre-auth on a fresh instance and commits an admin-account password reset (relying on the auto-seeded admin row existing) before any gated configuration step.

  • Fix commit referenced by advisory: 487bdfec545e805ae416e6ddf28651bd274d6a73 ("fix(api): harden pre-auth setup endpoints (#1041, #1044)").
  • Tested fixed/latest commits: 3.2.8 tag 265b449fad6d753f061a09aaa03fcd3eb739a266 (image :latest), 3.3.0-beta.2 tag c8f402fd687c443d91e6c6dc3474032b9a9182eb (image :3.3.0-beta.2), main HEAD b090ec7b02fd91a10bf45c7702ad392ae3ad65ef.

Reproduction Steps

  1. The self-contained script is bundle/vuln_variant/reproduction_steps.sh.
  2. What it does (idempotent, cleans up all containers/volumes on entry and exit):
    • Pulls the official images :3.2.6, :latest (=3.2.8), :3.3.0-beta.2.
    • For each image, starts a fresh instance with an empty Docker volume, waits for Application startup complete, captures the startup log ([Database] Created default admin user) and the image's module.__version__.VERSION.
    • Variant 1: POST /api/v1/auth/login with admin/adminadmin; on 200 + JWT, reuses the token cookie to call GET /api/v1/rss.
    • DEV rule-out: no-auth GET /api/v1/rss (expect 401).
    • Variant 2: on a fresh :latest instance, GET /api/v1/setup/status, then POST /api/v1/setup/complete with attacker creds pwned/pwnedpw1, then POST /api/v1/auth/login with those creds, then GET /api/v1/rss with the resulting JWT, then POST /api/v1/auth/login with admin/adminadmin (expect 401 post-takeover).
    • Writes HTTP artifacts to bundle/vuln_variant/artifacts/, startup logs to bundle/logs/vuln_variant/, and the runtime manifest to bundle/vuln_variant/runtime_manifest.json.
  3. Expected evidence of reproduction (all observed):
    • Startup line [Database] Created default admin user on 3.2.6, :latest (3.2.8), and :3.3.0-beta.2.
    • Variant 1 on :latest: login 200 + set-cookie: token=eyJ…sub=admin…; /api/v1/rss 200 [].
    • Variant 1 on :3.3.0-beta.2: login 200 + admin JWT.
    • Variant 2 on :latest: /setup/status {"need_setup":true,"version":"3.2.8"}; /setup/complete 200; login pwned/pwnedpw1 200 + JWT sub=pwned; /api/v1/rss 200; admin/adminadmin 401 "User not found".
    • DEV rule-out: no-auth /api/v1/rss 401 on every image.

Evidence

  • Run log: bundle/logs/vuln_variant/run.log
  • Startup logs: bundle/logs/vuln_variant/{vuln,latest,beta,setup}-startup.log
  • Fixed/latest version record: bundle/logs/vuln_variant/fixed_version.txt, latest_version.txt
  • HTTP artifacts: bundle/vuln_variant/artifacts/{vuln,latest,beta}-{login,rss,noauth-rss}.json, setup-{status,complete,login,rss,oldlogin}.json
  • Runtime manifest: bundle/vuln_variant/runtime_manifest.json
  • Source identity: bundle/vuln_variant/source_identity.json

Key excerpts (from the second idempotent run, :latest = 3.2.8):

Variant 1 — default creds on the patched version (artifacts/latest-login.json):

{ "method": "POST", "path": "/api/v1/auth/login", "status": 200,
  "set_cookie": "token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6…}; HttpOnly; Max-Age=86400; Path=/; SameSite=lax",
  "body": "{\"access_token\":\"eyJ…sub\":\"admin\"…\",\"token_type\":\"bearer\"}" }

artifacts/latest-rss.json: { "path": "/api/v1/rss", "status": 200, "body": "[]" }

Variant 2 — pre-auth /setup/complete takeover (artifacts/setup-status.jsonsetup-complete.jsonsetup-login.json):

{ "path": "/api/v1/setup/status", "status": 200, "body": "{\"need_setup\":true,\"version\":\"3.2.8\"}" }
{ "path": "/api/v1/setup/complete", "status": 200, "body": "{\"status\":true,…\"Setup completed successfully.\"…}" }
{ "path": "/api/v1/auth/login", "status": 200, "set_cookie": "token=eyJ…sub\":\"pwned\"…}" }
{ "path": "/api/v1/rss", "status": 200, "body": "[]" }
{ "path": "/api/v1/auth/login", "status": 401, "body": "{\"msg_en\":\"User not found\"}" }  // admin/adminadmin after takeover

DEV rule-out (artifacts/latest-noauth-rss.json): { "path": "/api/v1/rss", "status": 401, "body": "{\"detail\":\"Unauthorized\"}" }

Environment: Official ghcr.io/estrellaxd/auto_bangumi images on the host Docker daemon; AutoBangumi backend (Python 3.13, uvicorn/FastAPI, SQLite) inside Alpine containers; webui port 7892; HTTP probes executed in-container via docker exec python3 (the Docker bridge is not host-routable in this sandbox).

Recommendations / Next Steps

  1. Remove the hard-coded default admin seeding in add_default_user() (require the setup wizard to create the first admin, or generate a random one-time bootstrap password surfaced once to the operator).
  2. Gate POST /api/v1/auth/login behind setup completion (config/.setup_complete sentinel) so the default/seeded credentials cannot be used before initial configuration — closes Variant 1.
  3. Bind a one-time setup token / bootstrap secret to POST /api/v1/setup/complete (or otherwise authenticate the first-run takeover) so an unauthenticated remote party cannot reset the admin account on a fresh instance — closes Variant 2. Critically, the user-account reset in complete_setup step 1 must not commit before the caller is authorized.
  4. Treat 3.2.8 and 3.3.0-beta.2 as still affected by CVE-2026-58466 until a corrected fix that removes the default seeding and gates both /auth/login and /setup/complete is released.
  5. Regression tests: assert a fresh empty DB never contains a login-capable account with a known password; assert /auth/login fails before setup completion; assert /setup/complete requires a setup token.

Additional Notes

  • Bypass vs. alternate trigger: Variant 1 is a bypass — the original default-credential exploit reproduces on the patched and latest version because the fix does not address it. Variant 2 is an alternate trigger — a different pre-auth entry point (/api/v1/setup/complete) reaching the same fresh-instance admin-takeover impact; it is arguably a distinct CWE-306 first-run-takeover but is tightly coupled to the CVE root cause (it relies on the auto-seeded admin row existing and on the absence of a setup gate on /auth/login), and any fix to the default-credentials CVE must cover it.
  • Idempotency: reproduction_steps.sh was executed twice consecutively; both runs exited 0 with identical positive evidence (LATEST_LOGIN_OK=1, LATEST_ADMIN_OK=1, BETA_LOGIN_OK=1, SETUP_TAKEOVER_OK=1, DEV_BYPASS_ACTIVE=0). All containers/volumes are removed on entry and exit (trap cleanup EXIT); no leftover containers.
  • Trust boundary: Both variants cross the network trust boundary (unauthenticated remote HTTP → admin API) on a fresh, internet-exposed instance — the standard deployment exposed port 7892. This is not user-self-attack; it is remote unauthenticated takeover.
  • Scope honesty: The DEV_AUTH_BYPASS path was tested and ruled out for the official images rather than claimed, to avoid over-stating the finding.

CVE-2026-58466 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:48
0:00
session startedaccounts/fireworks/routers/glm-5p2-fast · CVE-2026-58466 · REPRO-20
0:02
0:03
web search
0:05
web search
0:07
0:08
0:16
0:16
extract_facts
no facts extracted
0:17
0:17
0:17
supportrepro
0:27
0:29
0:29
0:29
0:30
0:30
0:30
0:32
0:32
$ls -la /data/pruva/project-cache/86aad63e-3437-4d0f-ada8-659f4767b95d/ 2>/dev/null && echo "---REPO---" && ls -la /data/pruva/project-cache/86aad63e-3437-4d0f-ada8-659f4767b95d/repo/ 2>/dev/null; echo "---MIRROR---"; ls -la /data/pruva/project-cache/86aad63e-3437-4d0f-ada8-659f4767b95d/repo-mirrors/ 2>/dev/null
total 0
drwxr-xr-x 1 vscode vscode   24 Jul  3 14:29 .
drwxr-xr-x 1 vscode vscode 2254 Jul  3 14:29 ..
drwxr-xr-x 1 vscode vscode    0 Jul  3 14:29 repo-mirrors
---REPO---
---MIRROR---
total 0
drwxr-xr-x 1 vscode vscode  0 Jul  3 14:29 .
0:34
web search
0:39
0:43
$cd /data/pruva/project-cache/86aad63e-3437-4d0f-ada8-659f4767b95d && git clone https://github.com/EstrellaXD/Auto_Bangumi.git repo 2>&1 | tail -5; echo "---DONE---"; ls -la repo 2>/dev/null | head -20
3.3s
{"cwd":"/data/pruva/runs/c49850cc-fd88-4126-bea8-92b2a955dfff","duration_ms":3290,"exit_code":0,"stderr":"","stdout":"Cloning into 'repo'...\n---DONE---\ntotal 80\ndrwxr-xr-x 1 vscode vscode   364 Jul  3 14:30 .\ndrwxr-xr-x 1 vscode vscode    32 Jul  3 14:30 ..\n-rw-r--r-- 1 vscode vscode   467 Jul  3 14:30 .dockerignore\ndrwxr-xr-x 1 vscode vscode   122 Jul  3 14:30 .git\n-rw-r--r-- 1 vscode vscode   751 Jul  3 14:30 .gitattributes\ndrwxr-xr-x 1 vscode vscode    88 Jul  3 14:30 .github\n-rw-r--r-- 1 vscode vscode  3855 Jul  3 14:30 .gitignore\ndrwxr-xr-x 1 vscode vscode    78 Jul  3 14:30 .vscode\n-rw-r--r-- 1 vscode vscode 18201 Jul  3 14:30 CHANGELOG.md\n-rw-r--r-- 1 vscode vscode  5771 Jul  3 14:30 CLAUDE.md\n-rw-r--r-- 1 vscode vscode  8550 Jul  3 14:30 CONTRIBUTING.md\n-rw-r--r-- 1 vscode vscode   964 Jul  3 14:30 Dockerfile\n-rw-r--r-- 1 vscode vscode  1069 Jul  3 14:30 LICENSE\n-rw-r--r-- 1 vscode vscode  4337 Jul  3 14:30 README.md\n-rw-r--r-- 1 vscode vscode  1769 Jul  3 14:30 SECURITY.md\ndrwxr-xr-x 1 vscode vscode   134 Jul  3 14:30 backend\ndrwxr-xr-x 1 vscode vscode   274 Jul  3 14:30 docs\n-rw-r--r-- 1 vscode vscode   293 Jul  3 14:30 entrypoint.sh\n-rw-r--r-- 1 vsco… [truncated]
0:45
0:45
$cd /data/pruva/project-cache/86aad63e-3437-4d0f-ada8-659f4767b95d/repo && echo "=== CURRENT HEAD ===" && git log --oneline -3 && echo "=== FIX COMMIT EXISTS? ===" && git cat-file -t 487bdfec545e805ae416e6ddf28651bd274d6a73 2>&1 && echo "=== FIX COMMIT DIFF ===" && git show 487bdfec545e805ae416e6ddf28651bd274d6a73 2>&1 | head -200
{"cwd":"/data/pruva/runs/c49850cc-fd88-4126-bea8-92b2a955dfff","duration_ms":5,"exit_code":0,"stderr":"","stdout":"=== CURRENT HEAD ===\nb090ec7b Merge pull request #1049 from EstrellaXD/docs/security-contact\n8600bb7c docs(security): add working disclosure contact email\nabe98eda Merge pull request #1048 from EstrellaXD/3.2-dev\n=== FIX COMMIT EXISTS? ===\ncommit\n=== FIX COMMIT DIFF ===\ncommit 487bdfec545e805ae416e6ddf28651bd274d6a73\nAuthor: Estrella Pan <estrellaxd05@gmail.com>\nDate:   Thu Jul 2 11:39:10 2026 +0200\n\n    fix(api): harden pre-auth setup endpoints (#1041, #1044)\n    \n    /setup/test-downloader now validates the URL scheme (http/https only) like\n    test-rss already did, and accepts qBittorrent 5.2's 204 login response.\n    Raw exception and response detail is no longer echoed back from the\n    pre-authentication setup endpoints; it goes to the server log only.\n    \n    Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n    Claude-Session: https://claude.ai/code/session_014w1Z6Nxy6XTRgkFXqPr9Zh\n\ndiff --git a/backend/src/module/api/setup.py b/backend/src/module/api/setup.py\nindex cac73d27..92c879b7 100644\n--- a/backend/src/module/api/setup.py\n++… [truncated]
0:48
0:48
0:48

Artifacts and Evidence for CVE-2026-58466

Scripts, logs, diffs, and output captured during the reproduction.

bundle/ticket.md2.1 KB
bundle/ticket.json3.0 KB
bundle/logs/pull-vuln.log0.2 KB
bundle/logs/pull-fixed.log0.2 KB
bundle/logs/run.log16.4 KB
bundle/logs/vuln-1-startup.log2.0 KB
bundle/logs/vuln-2-startup.log2.0 KB
bundle/logs/fixed-1-startup.log2.0 KB
bundle/logs/fixed-2-startup.log2.0 KB
bundle/repro/ab_probe.py1.5 KB
bundle/repro/runtime_manifest.json1.3 KB
bundle/repro/validation_verdict.json0.9 KB
bundle/logs/vuln_variant/run.log2.7 KB
bundle/logs/vuln_variant/pull-auto_bangumi:3.2.6.log0.2 KB
bundle/logs/vuln_variant/pull-auto_bangumi:latest.log0.2 KB
bundle/logs/vuln_variant/pull-auto_bangumi:3.3.0-beta.2.log0.2 KB
bundle/logs/vuln_variant/vuln-startup.log2.0 KB
bundle/logs/vuln_variant/latest-startup.log2.0 KB
bundle/logs/vuln_variant/beta-startup.log2.1 KB
bundle/logs/vuln_variant/setup-startup.log2.0 KB
bundle/logs/vuln_variant/fixed_version.txt0.3 KB
bundle/logs/vuln_variant/latest_version.txt0.3 KB
bundle/vuln_variant/ab_probe2.py1.7 KB
bundle/vuln_variant/artifacts/vuln-noauth-rss.json0.1 KB
bundle/vuln_variant/artifacts/vuln-login.json0.5 KB
bundle/vuln_variant/artifacts/vuln-rss.json0.1 KB
bundle/vuln_variant/artifacts/latest-noauth-rss.json0.1 KB
bundle/vuln_variant/artifacts/latest-login.json0.5 KB
bundle/vuln_variant/artifacts/latest-rss.json0.1 KB
bundle/vuln_variant/artifacts/beta-noauth-rss.json0.1 KB
bundle/vuln_variant/artifacts/beta-login.json0.5 KB
bundle/vuln_variant/artifacts/beta-rss.json0.1 KB
bundle/vuln_variant/artifacts/setup-status.json0.2 KB
bundle/vuln_variant/artifacts/setup-complete.json0.3 KB
bundle/vuln_variant/artifacts/setup-login.json0.5 KB
bundle/vuln_variant/artifacts/setup-rss.json0.1 KB
bundle/vuln_variant/artifacts/setup-oldlogin.json0.2 KB
bundle/vuln_variant/runtime_manifest.json2.8 KB
bundle/vuln_variant/patch_analysis.md6.7 KB
bundle/vuln_variant/variant_manifest.json4.9 KB
bundle/vuln_variant/validation_verdict.json4.9 KB
bundle/vuln_variant/source_identity.json2.3 KB
bundle/vuln_variant/root_cause_equivalence.json3.7 KB
bundle/repro/reproduction_steps.sh14.9 KB
bundle/repro/rca_report.md10.6 KB
bundle/vuln_variant/reproduction_steps.sh19.4 KB
bundle/vuln_variant/rca_report.md15.9 KB
08 · How to Fix

How to Fix CVE-2026-58466

Upgrade EstrellaXD/Auto_Bangumi · standalone application (Python/FastAPI) to 3.2.8 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-58466 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-58466

How does the CVE-2026-58466 default-credential attack work?

Because the admin/adminadmin credentials are hard-coded and publicly visible in the source, an unauthenticated remote attacker submits them to the real authentication endpoint, POST /api/v1/auth/login, on a freshly deployed instance and receives a valid administrator JWT, gaining full control over RSS feed configuration, downloader configuration, server logs, and every authenticated API endpoint.

Which AutoBangumi versions are affected by CVE-2026-58466, and where is it fixed?

AutoBangumi versions before 3.2.8 are affected (reproduced on the official Docker image ghcr.io/estrellaxd/auto_bangumi:3.2.6). It is fixed in 3.2.8.

How severe is CVE-2026-58466?

It is rated critical severity with a CVSS score of 9.3. It is remote, unauthenticated, and low complexity, resulting in complete administrative takeover of a freshly deployed instance.

How can I reproduce CVE-2026-58466?

Download the verified script from this page and run it in an isolated environment against a fresh AutoBangumi instance before 3.2.8 with an empty users table. It submits the admin/adminadmin credentials to POST /api/v1/auth/login and shows a valid administrator JWT being issued, then confirms 3.2.8 no longer seeds the default account.
11 · References

References for CVE-2026-58466

Authoritative sources for CVE-2026-58466 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.