Skip to content

fix(deps): resolve audit advisories and update all dependencies to latest - #62

Merged
danielealbano merged 14 commits into
mainfrom
fix/security-advisories
Jul 8, 2026
Merged

fix(deps): resolve audit advisories and update all dependencies to latest#62
danielealbano merged 14 commits into
mainfrom
fix/security-advisories

Conversation

@danielealbano

Copy link
Copy Markdown
Owner

Summary

Resolves all outstanding cargo audit findings and brings every dependency to its latest version. cargo audit now exits clean (0 vulnerabilities); the tree shrank 416 → 382 crates as duplicate/unused deps were collapsed.

Security fixes (were failing CI Security Audit)

Advisory Crate Fix
RUSTSEC-2026-0066/-0112/-0113/-0145 astral-tokio-tar 0.5.6 via testcontainers 0.27.1 → 0.27.3 (pulls astral-tokio-tar 0.6.3)
RUSTSEC-2026-0189 / CVE-2026-42559 (DNS rebinding, HTTP transport) rmcp 0.8.5 rmcp → 2.1.0 (loopback-only Host validation on by default)
RUSTSEC-2021-0141 (unmaintained) dotenv removed (was unused)

Dependency upgrades

  • Compatible bumps (cargo update): anyhow, clap, futures, hyper, hyper-util, log, once_cell, regex, serde_json, tempfile, tokio, tower, and transitives.
  • Breaking bumps with migration: schemars 0.8 → 1 (aligns with rmcp, removes 3-way duplication) · thiserror 1 → 2 · env_logger 0.10 → 0.11 · mockall 0.12 → 0.15 · html2text 0.16 → 0.17 · toml 0.8 → 1 · reqwest 0.11 → 0.13.

rmcp 0.8.5 → 2.1.0 (breaking)

  • model::Contentmodel::ContentBlock (as_text() moved onto the enum; dropped the removed .raw wrapper).
  • ServerInfo/Implementation are now #[non_exhaustive]; built from Default + Implementation::new().with_website_url().
  • #[tool_handler(router = self.tool_router)] pins the cached router (2.x defaults to rebuilding per request).

azure_core / azure_identity 0.17 → 1.0 (breaking, auth)

azure_identity 1.0 removed DefaultAzureCredential. Replaced with an explicit ordered fallback chain that preserves the previous behavior:

ManagedIdentityCredential  (production / Azure-hosted)
        ↓
AzureCliCredential         (local dev)
        ↓
AzureDeveloperCliCredential (local dev)

Sources that fail to initialize are skipped. Migrated to the 1.0 API (TokenCredential moved to azure_core::credentials; get_token takes a scopes slice + options and returns AccessToken). Added a unit test asserting the chain always exposes at least one source.

Docs

Updated docs/PROJECT.md, docs/ARCHITECTURE.md (incl. mermaid diagrams, validated with mmdc) and the .claude/rules auth invariant to describe the new credential chain and the upgraded dependency versions.

Verification

  • cargo fmt --check, cargo clippy --features test-support -- -D warnings: clean
  • cargo test --features test-support: 163 tests pass across 13 binaries
  • cargo build --release: clean
  • cargo audit: exit 0, 0 vulnerabilities
  • Smoke test: MCP initialize handshake returns correct serverInfo/capabilities; binary starts and builds the credential chain without panic.

Note

The rmcp DNS-rebinding fix enables loopback-only Host validation by default. A --server deployment reached via a non-loopback hostname (e.g. behind a reverse proxy) will need its allowed hosts configured; a follow-up --allowed-host CLI flag is the intended path if that use case is needed.

testcontainers 0.27.1 pulled astral-tokio-tar 0.5.6, affected by
RUSTSEC-2026-0066/-0112/-0113/-0145 (PAX header desync, symlink chmod,
insufficient PAX validation). testcontainers 0.27.3 pulls
astral-tokio-tar 0.6.3, which is patched for all four. Dev-dependency
only; no source changes required.
rmcp 0.8.5 is affected by RUSTSEC-2026-0189 (CVE-2026-42559): the
Streamable HTTP server transport did not validate the Host header,
enabling DNS-rebinding attacks against locally running servers. Fixed
in rmcp >= 1.4.0; upgrade to the latest 2.1.0.

rmcp 2.x is a breaking change; migrate the affected API usage:
- model::Content -> model::ContentBlock (as_text() moved onto the enum;
  drop the removed .raw wrapper in the test helper).
- ServerInfo (InitializeResult) and Implementation are now
  #[non_exhaustive]; build them from Default plus Implementation::new()
  and the with_website_url builder instead of struct literals.
- #[tool_handler] now defaults to Self::tool_router() (rebuilt per
  request); pin it to the cached field via
  #[tool_handler(router = self.tool_router)] to preserve build-once.

StreamableHttpServerConfig::default() now enforces loopback-only Host
validation (the DNS-rebinding fix), which our transport picks up via
Default::default().
Routine cargo update: anyhow, clap, futures, hyper, hyper-util, log,
once_cell, regex, serde_json, tempfile, tokio, tower, html2text and
their transitive dependencies to the latest compatible versions. Lock
file only; no manifest or source changes.
Our tools declared schemars 0.8 while rmcp 2.1.0 requires schemars 1.0,
leaving three schemars versions (0.8, 0.9, 1.1) in the tree. Bump our
dependency to 1.x so the whole tree resolves to a single schemars 1.2.1.
Derive-only usage; no source changes required.
AzureError uses the standard derive(Error) + #[error]/#[from] pattern,
which is source-compatible with thiserror 2. No code changes required.
Only usage is env_logger::init() in main(), which is unchanged across
the 0.11 release. No code changes required.
MockAzureDevOpsApi via #[automock] and the expect_*/returning test API
are source-compatible with mockall 0.15. Integration tests pass.
The single from_read(bytes, width) -> Result call in
simplify_work_item_json is unchanged across 0.17. Simplification tests
pass, HTML-to-text output unchanged.
install.rs uses toml::Value, from_str, to_string_pretty and map::Map,
all retained in toml 1.x. Codex config round-trip tests pass.
dotenv 0.15 was declared but never referenced in any source or test.
It is unmaintained (RUSTSEC-2021-0141); removing it drops the advisory
warning and a dead dependency from the tree.
Our HTTP client uses the stable surface (Client, Method, header(),
json(), send(), text(), bytes(), bearer_auth(), header::HeaderMap),
all source-compatible with reqwest 0.13. Retains rustls-free
native-tls with json + multipart features.
azure_identity 1.0 removed DefaultAzureCredential. Replace it with an
ordered fallback chain that preserves the previous behavior: managed
identity first (production / Azure-hosted deployments), then Azure CLI
and Azure Developer CLI (local development). Sources that fail to
initialize are skipped so the remaining ones stay usable.

Migrate to the 1.0 API surface: TokenCredential moved to
azure_core::credentials; get_token now takes a scopes slice plus options
and returns AccessToken; token.token.secret() unchanged. Add a unit test
asserting the chain always exposes at least one source.
Update the dependency version tables (rmcp 2.1.0, reqwest 0.13, azure
1.0, thiserror 2, schemars 1, env_logger 0.11, mockall 0.15, html2text
0.17, toml 1, testcontainers 0.27.3; remove dotenv) and replace all
DefaultAzureCredential references with the new managed identity ->
Azure CLI -> Azure Developer CLI credential chain, including the
architecture diagrams.
azure_identity 1.0 removed DefaultAzureCredential; update the project
and MCP tooling rules to describe the managed identity -> Azure CLI ->
Azure Developer CLI credential chain that replaced it.
@danielealbano
danielealbano merged commit 62512a4 into main Jul 8, 2026
10 checks passed
@danielealbano
danielealbano deleted the fix/security-advisories branch July 8, 2026 13:07
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.

1 participant