Skip to content

fix(dashboard): reject stale WebUI assets in desktop-managed mode - #9898

Open
JosephTian876 wants to merge 1 commit into
AstrBotDevs:masterfrom
JosephTian876:fix/desktop-webui-version-enforcement
Open

fix(dashboard): reject stale WebUI assets in desktop-managed mode#9898
JosephTian876 wants to merge 1 commit into
AstrBotDevs:masterfrom
JosephTian876:fix/desktop-webui-version-enforcement

Conversation

@JosephTian876

@JosephTian876 JosephTian876 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Desktop-managed AstrBot passes an explicit --webui-dir. Even after #9518, an incomplete or version-mismatched explicit directory is only warned about and is still served. The desktop WebView can also reuse entry/static responses cached by an older release.

This PR makes the packaged desktop path fail closed while preserving standalone custom-WebUI compatibility. It also makes Dashboard replacement transactional and defines cache behavior that safely crosses upgrades.

Modifications / 改动点

  • Require a complete Dashboard entry graph and an exact Core/WebUI version match for explicit, data, and bundled directories in desktop-managed mode.

  • Preserve the existing standalone behavior: a custom explicit WebUI still logs a warning and is served outside desktop-managed mode.

  • Stage and validate downloaded Dashboard archives before replacement, restoring the previous directory if the swap fails.

  • Resolve the effective Dashboard again after repair instead of retaining a rejected path.

  • Serve HTML and assets/version with Cache-Control: no-store; require all other static resources to revalidate with no-cache.

  • Return Clear-Site-Data: "cache" only for a desktop-managed entry request carrying the Desktop-provided astrbot_bundle identity. Cookies and storage are not cleared.

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

An official Windows Desktop update from v4.27.0 to v4.27.5 reproduced the underlying failure conditions:

  • all 244 files in the new WebUI payload were installed with matching SHA-256 values;
  • the merge-style install retained 134 old files, including assets/version = v4.27.0;
  • Core/Desktop/code reported 4.27.5, while the public versions API reported WebUI v4.27.0;
  • the official navigation URL had no bundle identity, and the entry response had no cache policy.

A fresh HTTP request returned the new index and entry assets, so this evidence demonstrates the mixed-directory and stale-cache path; it is not presented as an end-to-end test of this unmerged commit.

Local verification at 5beffef1fd0eefb3119c7075d1b6d4626f6a98c3:

ruff format --check .
502 files already formatted

ruff check .
All checks passed!

pytest tests/test_dashboard.py tests/test_fastapi_v1_dashboard.py \
       tests/test_main.py tests/test_updater_socks.py \
       tests/unit/test_dashboard_dist_resolution.py
251 passed, 1 deselected

The deselected test requires Windows symlink privileges and is unrelated to this change. Regression coverage includes stale/missing markers, incomplete and path-escaping entries, standalone compatibility, staged replacement/rollback, release-tag versus commit version validation, and narrowly gated cache clearing for both / and /index.html.

No dependency, backend API schema, response schema, or OpenAPI definition changed, so no frontend API-client regeneration is required.

This Core PR enforces semantic version/entry compatibility and cache transition behavior. Exact executable-to-bundle cryptographic identity and live served-byte verification belong to the companion AstrBot Desktop change and are not claimed here.


Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc. / Not applicable: this is a bug fix and adds no user-facing feature.
  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 My changes do not introduce malicious code.

Summary by Sourcery

Fail closed on invalid desktop-managed Dashboard assets while making updates transactional and ensuring WebView resources revalidate safely across upgrades.

Bug Fixes:

  • Reject incomplete or version-mismatched Dashboard assets in desktop-managed mode to prevent stale or mixed WebUI bundles from being served.
  • Prevent standalone Dashboard updates from falling back to incomplete assets after download failures.
  • Apply cache-control and narrowly scoped cache clearing headers to prevent desktop WebView reuse of stale Dashboard resources.

Enhancements:

  • Make Dashboard package installation transactional by validating staged archives and preserving the previous installation for rollback on replacement failures.
  • Re-resolve Dashboard assets after repair so rejected explicit paths cannot remain active.
  • Retain warning-and-serve compatibility for mismatched custom WebUI directories in standalone mode.

Tests:

  • Add regression coverage for Dashboard completeness and version validation, transactional replacement and rollback, standalone compatibility, and desktop cache behavior.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="astrbot/core/updater.py" line_range="364" />
<code_context>
                 allow_insecure_ssl_fallback=False,
             )
         except Exception:
</code_context>
<issue_to_address>
**issue:** The `ensure_dashboard` docstring says the function ensures and returns Dashboard assets matching the running Core version, but the download-error fallback returns any complete `data/dist` without checking its version. Callers relying on the documented contract can serve stale assets after a failed download, especially outside desktop-managed mode where the subsequent resolver still permits a mismatched managed directory.

**Triggers:** When downloading or preparing the matching Dashboard package fails while an older but structurally complete `data/dist` exists.

**Suggested fix:** Either validate `_is_dist_compatible(data_dist_path, VERSION)` before returning the fallback or document explicitly that this method can return a complete but version-mismatched fallback.

```suggestion
            if _is_dist_compatible(data_dist_path, VERSION):
```
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 1 finding to address first, and if the asset validation or desktop fallback policy is wrong, startup could refuse a usable dashboard or serve an incorrect staged package, and the replacement persists in data/dist after a code revert. The package can be restored by rerunning or reinstalling the dashboard, so the damage is bounded and repairable rather than permanently irreversible.

Blocking findings: astrbot/core/updater.py:364


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread astrbot/core/updater.py Outdated
@JosephTian876

Copy link
Copy Markdown
Contributor Author

Desktop companion PR: AstrBotDevs/AstrBot-desktop#176. I validated the pair with an isolated Windows x64 NSIS/WebView2 upgrade from 4.27.0 to 4.27.5 using the updater passive arguments. The update intentionally retained 138 stale WebUI extras and the old WebView profile, while the running Core/code/WebUI versions were all 4.27.5, the served index/JS/CSS hashes matched the packaged manifest, and the entry response carried Cache-Control: no-store plus Clear-Site-Data: "cache". The same run also verified staged-resource fallback and fail-closed behavior when neither resource root matched. The Desktop PR documents the full evidence and limitations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants